Int*_*rer 4 python logging python-logging
我正在以这种方式使用 Python 日志记录:
logger = logging.getLogger("my_logger")
logger.info("Some text.")
Run Code Online (Sandbox Code Playgroud)
我有一堆物联网设备都在运行(制作日志)。他们将日志数据流式传输到数据库。为了区分来源,我需要包括来源 IP 地址。
有没有办法使用日志记录获取主机名?是否在 LogRecords 中跟踪/跟踪 IP 地址或主机名?
一般来说,将主机名添加到 LogRecord 的最佳方法是什么?
您可以通过添加将主机名放入日志消息的自定义日志过滤器和格式化程序来实现。
import logging, platform
class HostnameFilter(logging.Filter):
hostname = platform.node()
def filter(self, record):
record.hostname = HostnameFilter.hostname
return True
handler = logging.StreamHandler()
handler.addFilter(HostnameFilter())
handler.setFormatter(logging.Formatter('%(asctime)s %(hostname)s: %(message)s', datefmt='%b %d %H:%M:%S'))
logger = logging.getLogger()
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.info('Hello, world!')
Run Code Online (Sandbox Code Playgroud)
一个更简单的解决方案是使用主机名预先填充格式行。例如:
logging.basicConfig(
#... your logging configuration,
format="%(asctime)s {} %(message)s".format(socket.gethostname())
)
Run Code Online (Sandbox Code Playgroud)
会生成一个格式行,例如
"%(asctime)s some-hostname %(message)s"
Run Code Online (Sandbox Code Playgroud)
缺点是,如果主机名更改,您需要重新启动服务/应用程序。对于大多数应用程序来说,这通常不是问题,特别是在 docker/k8s 上运行时
import logging
from logging import Formatter
from logging.handlers import SysLogHandler
from socket import gethostname
hostname = socket.gethostname()
syslog = SysLogHandler(('my.logging.domain', 601))
syslog.setFormatter(
Formatter(
'{asctime} %s {name}: {levelname:8} {message}' % hostname,
datefmt='%b %d %H:%M:%S',
style='{'
)
)
logger = logging.getLogger('myident')
logger.addHandler(syslog)
logger.setLevel(logging.DEBUG)
logger.info('Hello, world!')
Run Code Online (Sandbox Code Playgroud)
基于1和2,但跳过过滤器/动态主机名。使用 Python 3.9.15 和 Papertrail 进行测试。