PyLint 消息:日志格式插值

PyLint message: logging-format-interpolation

对于以下代码:

logger.debug('message: {}'.format('test'))

pylint 产生以下警告:

logging-format-interpolation (W1202):

Use % formatting in logging functions and pass the % parameters as arguments Used when a logging statement has a call form of “logging.(format_string.format(format_args...))”. Such calls should use % formatting instead, but leave interpolation to the logging function by passing the parameters as arguments.

我知道我可以关闭此警告,但我想了解它。我假设使用 format() 是在 Python 中打印出语句的首选方式 3. 为什么这对于记录器语句不正确?

记录器语句不正确,因为它依赖于以前的“%”格式(如字符串)使用提供给记录器调用的额外参数来提供此字符串的惰性插值。例如而不是做:

logger.error('oops caused by %s' % exc)

你应该做的

logger.error('oops caused by %s', exc)

因此只有在消息实际发出时才会插入字符串。

使用 .format() 时无法使用此功能。


根据 logging 文档的 Optimization 部分:

Formatting of message arguments is deferred until it cannot be avoided. However, computing the arguments passed to the logging method can also be expensive, and you may want to avoid doing it if the logger will just throw away your event.

也许这个 time differences 可以帮到你。

以下描述不是您问题的答案,但可以帮助人们。

如果您想使用 fstrings(文字字符串插值)进行日志记录,那么您可以使用 disable=logging-fstring-interpolation.pylintrc 文件中禁用它,请参阅:related issue and comment.

您也可以禁用 logging-format-interpolation.


对于pylint 2.4:

.pylintrc 文件中有 3 个日志样式选项:oldnewfstr

2.4 and removed in 2.5

中添加了

fstr 选项

来自 .pylintrc 文件 (v2.4) 的描述:

[LOGGING]

# Format style used to check logging format string. `old` means using %
# formatting, `new` is for `{}` formatting,and `fstr` is for f-strings.
logging-format-style=old

对于 old (logging-format-style=old):

foo = "bar"
self.logger.info("foo: %s", foo)

对于 new (logging-format-style=new):

foo = "bar"
self.logger.info("foo: {}", foo)
# OR
self.logger.info("foo: {foo}", foo=foo)

注意:你可以使用.format()即使你selectnew选项.

pylint 仍然对这段代码给出相同的 警告

self.logger.info("foo: {}".format(foo))  # W1202
# OR
self.logger.info("foo: {foo}".format(foo=foo))  # W1202

对于 fstr (logging-format-style=fstr):

foo = "bar"
self.logger.info(f"foo: {foo}")

就我个人而言,我更喜欢 fstr 选项,因为 PEP-0498

根据我的经验,比优化(对于大多数用例)惰性插值更有说服力的原因是它可以很好地与 Sentry 等日志聚合器配合使用。

考虑 'user logged in' 日志消息。如果将用户插入到格式字符串中,那么有多少用户就有多少不同的日志消息。如果你像这样使用惰性插值,日志聚合器可以更合理地将其解释为具有一堆不同实例的相同日志消息。

可能是几年后,但前几天不得不处理这个问题,我变得简单了;刚刚在记录器之前格式化了字符串。

message = 'message: {}'.format('test')
logger.debug(message)

这样就不需要更改日志中的任何设置,如果以后想要更改为正常打印,则无需更改格式或代码。