我希望将以下日志点添加到我的应用程序中,并在控制台上显示extra
的完整内容,例如
logger.info('Status', extra={'foo':data})
logger.info('Status', extra={'bar':data})
logger.info('Status', extra={'foo':data, 'bar':data})
我希望看到:
2016-10-10 15:28:31,408, INFO, Status, foo=data
2016-10-10 15:38:31,408, INFO, Status, bar=data
2016-10-10 15:48:31,408, INFO, Status, foo=data, bar=data
这甚至可能吗?根据官方日志记录文档,Formatter
必须使用期望foo
和bar
的格式字符串进行设置,但在我的情况下,我想要的只是转储整个{{1}的kwargs。 1}}事先没有extra
和foo
。
答案 0 :(得分:1)
现在尝试解决同样的问题。问题是传递给extra的任何东西都被添加为LogRecord的属性,格式化程序无法将其与其他LogRecord属性区分开来。我只想出一种创建虚拟记录并将其与实际记录进行比较的hackish方法:
class ExtraLogFormatter(logging.Formatter):
def format(self, record):
dummy = logging.LogRecord(None,None,None,None,None,None,None)
extra_txt = ''
for k,v in record.__dict__.items():
if k not in dummy.__dict__:
extra_txt += ', {}={}'.format(k,v)
message = super().format(record)
return message + extra_txt
答案 1 :(得分:1)
格式化程序使用的LogRecord
提供您所需的信息:
extra
在其中被推为structured data
; msg
获得。 尽管我不知道可以使用简单的格式化程序配置从此extra
打印所有键值的选项,但是可以选择使用自定义格式化程序来打印。
在此示例中,它显示了如何用结构化数据和文本消息的串联替换日志中的文本消息。
import logging
class ExtraFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> str:
if hasattr(record, "structured_data") and 'user' in record.structured_data:
# Override message with extra info
record.msg = "%s %s" % (
self._join_extra(record.structured_data['user']),
record.msg
)
return super().format(record)
@staticmethod
def _join_extra(extra: dict) -> str:
return "[%s]" % ", ".join([
'%s:%s' % (key, value)
for (key, value) in extra.items()
])
与此配合,使用:
logger.debug("Hello world!", extra={"foo", "bar", "baz": "qux"})
会让您:
[2018-11-26 15:43:33,794] [INFO] [__main__] [foo:bar, baz:qux] Hello world!
答案 2 :(得分:1)
以extra
传递的对象条目将成为LogRecord的成员变量。
logger.info('Status', extra={'my_params':{'foo':3, 'bar':4}})
然后您可以将其格式化为:
handler.setFormatter(logging.Formatter('%(message)s %(my_params)s'))
这将导致以下日志:
#> Status {'foo':3, 'bar':4}}
这假定您在登录时可以控制“额外”参数。