如何处理日志消息模板中的Python格式错误?

时间:2019-06-25 13:22:16

标签: python templates logging format

有时我会弄乱Python logging模块的模板字符串格式,例如:

import logging
logging.warning('%d', 1, 2)  # BROKEN

在控制台中,我可以看到一条警告消息(省略了堆栈跟踪):

--- Logging error ---
Traceback (most recent call last):
  File ".../python3.7/logging/__init__.py", line 1034, in emit
    msg = self.format(record)
  File ".../python3.7/logging/__init__.py", line 880, in format
    return fmt.format(record)
  File ".../python3.7/logging/__init__.py", line 619, in format
    record.message = record.getMessage()
  File ".../python3.7/logging/__init__.py", line 380, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
    ...
Message: '%d'
Arguments: (1, 2)

但是,我的消息和此警告都没有发送到日志处理程序,该处理程序实际上会将其写到日志文件,也不会发送到logstash等。

我知道我可以使用logging-too-few-args(E1206)和logging-too-many-args(E1205)在pylint中找到这些错误,但是我仍然希望使用某种运行时回退如果其中一个滑过。

因此,除非有人从Python外部监视stderr,否则这些错误很容易被忽略。

是否仍然可以使用标记和基本要素来记录消息,例如:

  

[LogBug] message ='%d',参数=(1、2)

这样,原始信息仍然会保留,并且可以定期扫描日志文件中的[LogBug]标记。

1 个答案:

答案 0 :(得分:0)

也许可以使用try / except吗?可能使用re从异常消息中提取消息和参数

import re

try:
    logging.warning('%d', 1, 2)
except TypeError as e:
    message = re.search(r'Message: ([^\n]*)[\n$]', e.message).group(1)
    arguments = re.search(r'Arguments: ([^\n]*)[\n$]', e.message).group(1)
    logging.error("[LogBug] message=%s, arguments=%s",message, arguments)
    # if you want, you could re-raise this exception

如果您确实采用了该解决方案,则在TypeError格式不符合您期望的格式的情况下,您可能还必须考虑错误处理,因此正则表达式将无法正常工作,并会引发{{ 1}},当您尝试在其上调用AttributeError时。

您可以进行此操作的深度没有限制,但是,如果您真的确定该检查可以正常工作,则它可以捕获其他检查。


或者,如果您使用的是最新版本的python,则可以不使用.group()包来进行参数插入,而可以使用格式字符串,这样就不会有这种歧义的余地了:

logging