获取更有用的';日志记录';python中的模块错误输出
我正在使用python的获取更有用的';日志记录';python中的模块错误输出,python,python-3.x,Python,Python 3.x,我正在使用python的logger模块(python 3.x版,但这不重要),我注意到格式字符串中的错误报告如下: Traceback (most recent call last): File "/usr/lib/python3.1/logging/__init__.py", line 770, in emit msg = self.format(record) File "/usr/lib/python3.1/logging/__init__.py", line 650,
logger
模块(python 3.x版,但这不重要),我注意到格式字符串中的错误报告如下:
Traceback (most recent call last):
File "/usr/lib/python3.1/logging/__init__.py", line 770, in emit
msg = self.format(record)
File "/usr/lib/python3.1/logging/__init__.py", line 650, in format
return fmt.format(record)
File "/usr/lib/python3.1/logging/__init__.py", line 438, in format
record.message = record.getMessage()
File "/usr/lib/python3.1/logging/__init__.py", line 308, in getMessage
msg = msg % self.args
TypeError: %d format: a number is required, not str
如您所见,没有提到实际错误(在我的代码中)的位置。顺便说一句,我的代码有错:
logging.debug('This is a string %d', str(foo))
在%s
中更改%d
解决了问题
我的问题是:如何从
日志记录
模块输出中获得一些稍微有用的信息?我必须自己写日志吗?在哪里调整记录器
模块 如果我正确理解您的意思,这里的问题是,回溯不会给您任何指示,说明错误是从代码中的何处产生的。不知怎的,你不得不追查那条线
logging.debug('This is a string %d', str(foo))
你自己
日志记录模块的设计使emit()调用期间发生的异常由处理程序的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.
"""
您可以重写此方法以查看完整的回溯:
import sys
import logging
class MyStreamHandler(logging.StreamHandler):
def handleError(self, record):
raise
if __name__ == '__main__':
console = MyStreamHandler()
logger=logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(console)
logger.debug('%d','ahh')
屈服
Traceback (most recent call last):
File "/tmp/test.py", line 25, in <module>
logger.debug('%d','ahh')
File "/usr/lib/python2.6/logging/__init__.py", line 1036, in debug
self._log(DEBUG, msg, args, **kwargs)
File "/usr/lib/python2.6/logging/__init__.py", line 1165, in _log
self.handle(record)
File "/usr/lib/python2.6/logging/__init__.py", line 1175, in handle
self.callHandlers(record)
File "/usr/lib/python2.6/logging/__init__.py", line 1212, in callHandlers
hdlr.handle(record)
File "/usr/lib/python2.6/logging/__init__.py", line 673, in handle
self.emit(record)
File "/usr/lib/python2.6/logging/__init__.py", line 796, in emit
self.handleError(record)
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: %d format: a number is required, not str
就在我要发布这篇文章的时候,Unutbu打败了我。但不管怎样,这就是: 您可以尝试将正在使用的任何处理程序子类化(下面的示例使用StreamHandler),并使用一个函数将format方法覆盖到try:块中
import traceback, logging
class MyStreamHandler(logging.StreamHandler):
def format(self, record):
try:
return logging.StreamHandler.format(self, record)
except TypeError:
# Print a stack trace that includes the original log call
traceback.print_stack()
if __name__ == "__main__":
log = logging.getLogger("testlogger")
handler = MyStreamHandler()
log.addHandler(handler)
log.error("Try interpolating an int correctly: %i", 1)
log.error("Now try passing a string to an int: %d", 'abc')
log.error("And then a string to a string %s", 'abc')
给我:
Try interpolating an int correctly: 1
File "logtest2.py", line 19, in ?
log.error("Now try passing a string to an int: %d", 'abc')
File "/usr/lib64/python2.4/logging/__init__.py", line 999, in error
apply(self._log, (ERROR, msg, args), kwargs)
File "/usr/lib64/python2.4/logging/__init__.py", line 1079, in _log
self.handle(record)
File "/usr/lib64/python2.4/logging/__init__.py", line 1089, in handle
self.callHandlers(record)
File "/usr/lib64/python2.4/logging/__init__.py", line 1126, in callHandlers
hdlr.handle(record)
File "/usr/lib64/python2.4/logging/__init__.py", line 642, in handle
self.emit(record)
File "/usr/lib64/python2.4/logging/__init__.py", line 731, in emit
msg = self.format(record)
File "logtest2.py", line 8, in format
traceback.print_stack()
None
And then a string to a string abc
我不会把它留在任何生产代码中,但它应该可以帮助您找到类似的东西
log.error("%d", 'a string')
我想,如果您的日志调用错误,最好是静默失败,而不是导致应用程序从日志中获得异常。在这种想法下,模块应该故意打印(或者最好是错误记录)调用上方的所有堆栈帧,而不仅仅是异常帧。我建议在Python邮件列表中提出这个问题。可能是给用户的。谢谢,这正是我所希望的。这是一个有点令人不安的是,这样的例子不在第2行的教程。但也许我看得不够仔细。谢谢。我更喜欢你的答案,因为它最后才显示错误信息,而不是在最上面。谢谢
log.error("%d", 'a string')