使用 `str.format` 模板化日志消息

Using `str.format` to template log messages

我正在尝试在我的日志记录中使用 str.format 样式模板。似乎无法正常工作。

>>> import logging
>>> logging.basicConfig(filename='/tmp/example', format='{asctime} - {levelname} - {message}', style='{', level=logging.INFO)
>>> logger = logging.getLogger(__name__)
>>> logger.warning('blah')
>>> logger.warning('{foo:03d}', {'foo': 42})

实际输出:

2017-02-23 16:11:45,695 - WARNING - blah
2017-02-23 16:12:11,432 - WARNING - {foo:03d}

预期输出:

2017-02-23 16:11:45,695 - WARNING - blah
2017-02-23 16:12:11,432 - WARNING - 042

我在此设置中缺少什么?

我不想看到在记录之前格式化字符串的解决方法,或者 Python 2 solutions 使用旧的 % 样式模板。

显然 style 参数仅适用于有关消息的信息(例如时间戳、严重性等),而不适用于实际消息。

来自 logger.warning 的文档字符串:

warning(msg, *args, **kwargs) method of logging.Logger instance
    Log 'msg % args' with severity 'WARNING'.

似乎 msg 总是使用旧式格式进行格式化,因此甚至没有考虑记录器的 style 参数。

logging HOWTO 包含更多信息:

... you cannot directly make logging calls using str.format() or string.Template syntax, because internally the logging package uses %-formatting to merge the format string and the variable arguments. There would no changing this while preserving backward compatibility, since all logging calls which are out there in existing code will be using %-format strings.

"I'm not interested to see workarounds that format the string before it's logged" 为什么不呢?旧样式也在记录之前对其进行格式化...您可以将行放在 logger.warning 调用中进行格式化,并且它在功能上没有任何改变。如果 {foo:42} 只是一个更大的字典中的一个成员,你可以这样做:

for key,val in warningsDictionary.iteritems():
    logger.warning('{'+key+':'+format(val,'03')+'}')

这是否足够取决于您实际尝试做的事情。