我使用
logging.fileConfig()
配置了日志记录。我有一个根记录器,用于使用 SysLogHandler('/dev/log', handlers.SysLogHandler.LOG_USER)
的处理程序
这一切都运行得很好,我在
/var/log/user.log
中看到了我的日志条目
问题是如何将 syslog ident 字符串设置为 python 以外的其他字符串?标准库中的 syslog 模块似乎允许在打开日志时进行设置,但日志记录处理程序不提供此功能。
解决方案是子类化
SysLogHandler
并在其emit方法中使用syslog库吗?这是一个仅限 UNIX 的程序,因此直接使用 syslog 不会造成可移植性问题。
这有点旧,但应该在这里记录新信息,这样人们就不需要编写自己的系统日志处理程序。
自 Python 3.3 起,SysLogHandler 有一个
.ident
类属性正是用于此目的;默认值为 ''。
示例:
import logging
from logging.handlers import SysLogHandler
h = SysLogHandler(address=('some.destination.com',514), facility=SysLogHandler.LOG_LOCAL6)
h.setFormatter(
logging.Formatter('%(name)s %(levelname)s %(message)s')
)
h.ident = 'conmon'
syslog = logging.getLogger('syslog')
syslog.setLevel(logging.DEBUG)
syslog.addHandler(h)
syslog.debug('foo syslog message')
接受 RFC3164 消息的系统日志实现应将消息的第一部分(示例中的
"foo:"
)识别为标签。
MSG 部分有两个字段,称为 TAG 字段和 CONTENT 场地。 TAG 字段中的值将是程序的名称或 生成消息的进程。
Python 代码..
import logging
from logging.handlers import SysLogHandler
h = SysLogHandler(address='/dev/log')
h.setFormatter(logging.Formatter('foo: %(message)s'))
logging.getLogger().addHandler(h)
logging.error('bar')
..将其发送到系统日志套接字
connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 10) = 0
sendto(3, "<11>foo: bar\0", 13, 0, NULL, 0) = 13
close(3)
这又会在 systemd 的日志中生成此内容。
Dec 13 14:48:20 laptop foo[1928]: bar
期刊消息详情:
{
..
"PRIORITY" : "3",
"SYSLOG_FACILITY" : "1",
"SYSLOG_IDENTIFIER" : "foo",
"MESSAGE" : "bar",
"_PID" : "1928",
}
它适用于 Py2.6、2.7、3.4、3.5 和 Systemd 的 syslog 服务器。它也可以与其他系统日志实现(如果它们接受 RFC3164)消息一起使用。当 python 的 SysLogHandler 默认为较新的 RFC5424 时,此解决方案可能会失败。
AFAIK,ident 字符串是 syslog API 的产物,请参阅此页面。它只是使用 C argv[0],这当然是“python”。
令我惊讶的是,您使用
SysLogHandler
和域套接字来获取此信息,因为跨域或 TCP 套接字发送到系统日志守护进程的消息只是一个优先级为 SysLogHandler
没有指定 ident 字符串,因为它不使用 syslog API(在某些版本中存在一些线程安全问题,IIRC)。
对于 Python 2.7,你可以这样做:
class MySysLogHandler(logging.handlers.SysLogHandler):
def __init__(self):
super(MySysLogHandler, self).__init__(address='/dev/log')
def emit(self, record):
priority = self.encodePriority(self.facility, self.mapPriority(record.levelname))
record.ident = "My[" + str(priority) + "]:"
super(MySysLogHandler, self).emit(record)
handler = MySysLogHandler()
handler.formatter = logging.Formatter(fmt="%(ident)s %(levelname)s: %(message)s")
logging.root.addHandler(handler)
logging.info("hello world")
这将在系统日志中产生:
Sep 3 16:28:53 hostname My[14]: INFO: hello world