9

我已经使用 logging.fileConfig() 配置了日志记录。我有一个根记录器转到使用 SysLogHandler('/dev/log', handlers.SysLogHandler.LOG_USER) 的处理程序

这一切都运行良好,我在 /var/log/user.log 中看到了我的日志条目

问题是如何将 syslog ident 字符串设置为 python 以外的字符串?似乎标准库中的 syslog 模块允许在打开日志时进行设置,但日志处理程序不提供此功能。

解决方案是继承 SysLogHandler 并在它的 emit 方法中使用 syslog 库吗?这是一个仅适用于 unix 的程序,因此直接使用 syslog 不会造成可移植性问题。

4

4 回答 4

9

这有点旧,但应该在这里记录新信息,这样人们就不会觉得有必要编写自己的 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')
于 2013-10-26T20:02:52.877 回答
8

接受RFC3164消息的Syslog 实现应该将消息的第一部分("foo:"在示例中)识别为 TAG。

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 服务器。它也可以与其他 syslog 实现(如果它们接受 RFC3164)消息一起使用。当 python 的 SysLogHandler 默认为较新的 RFC5424 时,此解决方案可能会中断。

于 2016-12-13T16:58:22.943 回答
4

AFAIK,ident 字符串是 syslog API 的工件,请参阅此页面。它只是使用 C argv[0] 当然是“python”。

我很惊讶您将它SysLogHandler与域套接字一起使用,因为跨域或 TCP 套接字发送到 syslog 守护程序的消息只是一个字符串,其优先级在 <尖括号> 中,后跟格式化消息和 NUL 字节。没有指定 ident 字符串SysLogHandler,因为它不使用 syslog API(在某些版本中存在一些线程安全问题,IIRC)。

于 2010-11-23T22:16:52.393 回答
2

对于 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

于 2015-09-03T23:03:48.363 回答