使用Python日志时查找格式错误的来源
当我有很多不同的模块在使用标准的Python日志模块时,下面的错误追踪信息对我找到哪里有格式不正确的日志语句帮助不大:
Traceback (most recent call last):
File "/usr/lib/python2.6/logging/__init__.py", line 768, in emit
msg = self.format(record)
File "/usr/lib/python2.6/logging/__init__.py", line 648, in format
return fmt.format(record)
File "/usr/lib/python2.6/logging/__init__.py", line 436, in format
record.message = record.getMessage()
File "/usr/lib/python2.6/logging/__init__.py", line 306, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
我刚开始使用Python的日志模块,所以可能我忽略了一些明显的东西。我不确定这个错误追踪信息是否因为我在使用绿色线程而变得没用,还是说这在日志模块中是正常的。不过任何帮助都非常感谢。我愿意修改源代码,任何能让我找到问题所在的方法都可以。
5 个回答
4
这其实不是对问题的直接回答,但希望能帮助像我一样的初学者理解日志模块。
我的问题是,我把所有的print都换成了logging.info,结果像这样有效的代码 print('a',a)
就变成了 logging.info('a',a)
(但正确的写法应该是 logging.info('a %s'%a)
)。
这个问题在 如何追踪日志错误? 中也有提到,但在我的研究中没有找到相关信息。
6
与其直接修改已经安装的Python代码,你还可以通过这种方式找到错误:
def handleError(record):
raise RuntimeError(record)
handler.handleError = handleError
这里的handler是导致问题的处理程序之一。现在,当格式错误发生时,你就能看到出错的位置。
5
日志模块的设计目的是为了防止糟糕的日志信息影响到其他代码的运行,所以它的 emit
方法会捕捉错误,并把这些错误交给一个叫 handleError
的方法处理。对你来说,最简单的办法就是暂时编辑一下 /usr/lib/python2.6/logging/__init__.py
文件,找到 handleError
。它看起来大概是这样的:
def handleError(self, record):
"""
Handle errors which occur during an emit() call.
This method should be called from handlers when an exception is
encountered during an emit() call. If raiseExceptions is false,
exceptions get silently ignored. This is what is mostly wanted
for a logging system - most users will not care about errors in
the logging system, they are more interested in application errors.
You could, however, replace this with a custom handler if you wish.
The record which was being processed is passed in to this method.
"""
if raiseExceptions:
ei = sys.exc_info()
try:
traceback.print_exception(ei[0], ei[1], ei[2],
None, sys.stderr)
sys.stderr.write('Logged from file %s, line %s\n' % (
record.filename, record.lineno))
except IOError:
pass # see issue 5971
finally:
del ei
现在暂时编辑一下它。在开头插入一个简单的 raise
语句,这样可以确保错误会被传递到你的代码中,而不是被吞掉。一旦你解决了问题,就把日志代码恢复到原来的样子。