Python中的多行日志记录

Python中的多行日志记录,python,logging,python-3.x,Python,Logging,Python 3.x,我正在使用Python3.3.5和日志模块将信息记录到本地文件(来自不同线程)。在有些情况下,我想输出一些额外的信息,而不知道这些信息是什么(例如,可能是一行文字或一条口述) 我想做的是在日志记录被写入之后,将这些附加信息添加到日志文件中。此外,只有当日志级别为错误(或更高)时,才需要附加信息 理想情况下,它看起来像: 2014-04-08 12:24:01 - INFO - CPU load not exceeded 2014-04-08 12:24:26 - INFO - S

我正在使用Python3.3.5和日志模块将信息记录到本地文件(来自不同线程)。在有些情况下,我想输出一些额外的信息,而不知道这些信息是什么(例如,可能是一行文字或一条口述)

我想做的是在日志记录被写入之后,将这些附加信息添加到日志文件中。此外,只有当日志级别为错误(或更高)时,才需要附加信息

理想情况下,它看起来像:

2014-04-08 12:24:01 - INFO     - CPU load not exceeded
2014-04-08 12:24:26 - INFO     - Service is running
2014-04-08 12:24:34 - ERROR    - Could not find any active server processes
Additional information, might be several lines.
Dict structured information would be written as follows:
key1=value1
key2=value2
2014-04-08 12:25:16 - INFO     - Database is responding
除了编写一个定制的日志格式化程序,我找不到多少适合我的要求。我读过关于过滤器和上下文的文章,但这似乎不是一个很好的匹配

或者,我可以使用标准I/O写入文件,但日志模块中已经存在大部分功能,而且它是线程安全的


如有任何意见,将不胜感激。如果确实需要自定义日志格式化程序,那么任何关于从何处开始的指针都会非常棒。

我只是在输出文本中添加了
\n
符号。

似乎我在定义日志格式化程序字符串时犯了一个小错误:不小心转义了换行符,我错误地认为将多行输出写入日志文件是不可能的

为@Barafu指出这一点而干杯(这就是为什么我给了他正确的答案)

以下是示例代码:

import logging
lf = logging.Formatter('%(levelname)-8s - %(message)s\n%(detail)s')
lh = logging.FileHandler(filename=r'c:\temp\test.log')
lh.setFormatter(lf)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
log.addHandler(lh)
log.debug('test', extra={'detail': 'This is a multi-line\ncomment to test the formatter'})
结果输出如下所示:

DEBUG    - test
This is a multi-line
comment to test the formatter
警告: 如果没有要记录的详细信息,并且您传递了一个空字符串,那么记录器仍然会输出一个换行符。因此,剩下的问题是:我们如何使这成为有条件的


一种方法是在实际记录信息之前更新日志格式化程序,如所描述的。

记住,许多人认为多行日志消息是一种错误的做法,您可以使用<代码> Ext>/Cult>属性,并使用自定义格式化程序将内容附加到要显示的消息中。(查看日志记录包中“extra”的用法)

该代码输出:

DEBUG:root:Nothing special here... Keep walking
INFO:extra_logger:This shows extra
        foo: bar
        baz: loren
DEBUG:extra_logger:Now you should be seeing it!

我仍然建议在自定义筛选器中调用
super
filter
函数,主要是因为该函数决定是否显示消息(例如,如果您的记录器级别设置为
logging.INFO
,并且您使用
extra\u logger.debug
,则不应看到该消息,如上面的示例所示)

我在较小的应用程序中使用了一个简单的行拆分器:

for line in logmessage.splitlines():
            writemessage = logtime + " - " + line + "\n"
            logging.info(str(writemessage))
请注意,这不是线程安全的,可能只应在日志卷记录应用程序中使用


但是,您几乎可以输出到日志,因为这将保留您的格式。例如,我使用它来输出JSON API响应,其格式为:
JSON.dumps(已解析,缩进=4,排序_keys=True)

如果我将日志格式化程序定义为
lf=logging.formatter('%(levelname)-8s-%(message)s\\n%(详细信息)s'))
并定义一个
FileHandler
将日志写入文件,输出将包含
\n
而不是转换为换行符。遵循“日志记录食谱”。使用模板的
str.format()
样式而不是默认的基于%的样式-然后它将考虑特殊符号。
for line in logmessage.splitlines():
            writemessage = logtime + " - " + line + "\n"
            logging.info(str(writemessage))