loggingPythonexception的最佳方法
我打印我的exception到一个日志文件目前使用:
try: # coode in here except Exception, e: logging.error(e)
我可以打印关于exception的更多信息和生成它的代码,而不仅仅是exceptionstring? 像行号或栈跟踪会很好。
logger.exception
做到这一点。
例如:
import logging try: 1/0 except Exception as e: logging.exception("message")
输出:
ERROR:root:message Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: integer division or modulo by zero
@Paulo Check notes“,请注意,在Python 3中,必须在except
部分内部调用logging.exception
方法,如果在任意位置调用此方法,您可能会遇到一个奇怪的例外情况,文档会提醒您。
关于logging.exception
一个好消息, SiggyF的答案没有显示,你可以传入一个任意的消息,并且日志仍然会显示所有exception细节的完整回溯:
import logging try: 1/0 except Exception: logging.exception("Deliberate divide by zero traceback")
使用sys.stderr
打印错误的默认(最近版本)logging行为,它看起来像这样:
>>> import logging >>> try: ... 1/0 ... except Exception: ... logging.exception("Deliberate divide by zero traceback") ... ERROR:root:Deliberate divide by zero traceback Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: integer division or modulo by zero
使用exc_info选项可能会更好,允许您select错误级别(如果使用exception
,它将始终显示error
):
try: # do something here except Exception as e: logging.error(e, exc_info=True)
引用
如果您的应用程序以其他方式进行
logging
而不使用logging
模块呢?
现在,可以在这里使用traceback
。
import traceback def log_traceback(ex, ex_traceback=None): if ex_traceback is None: ex_traceback = ex.__traceback__ tb_lines = [ line.rstrip('\n') for line in traceback.format_exception(ex.__class__, ex, ex_traceback)] exception_logger.log(tb_lines)
-
在Python 2中使用它:
try: # your function call is here except Exception as ex: _, _, ex_traceback = sys.exc_info() log_traceback(ex, ex_traceback)
-
在Python 3中使用它:
try: x = get_number() except Exception as ex: log_traceback(ex)
如果您使用普通日志 – 所有的日志logging应符合此规则: one record = one line
。 遵循这个规则,你可以使用grep
和其他工具来处理你的日志文件。
但是回溯信息是多线的。 所以我的答案是在这个线程上面提到的zangw的一个扩展版本的解决scheme。 问题是,回溯行可能有\n
里面,所以我们需要做一些额外的工作来摆脱这个行结束:
import logging logger = logging.getLogger('your_logger_here') def log_app_error(e: BaseException, level=logging.ERROR) -> None: e_traceback = traceback.format_exception(e.__class__, e, e.__traceback__) traceback_lines = [] for line in [line.rstrip('\n') for line in e_traceback]: traceback_lines.extend(line.splitlines()) logger.log(level, traceback_lines.__str__())
之后(当你将分析你的日志),你可以从你的日志文件复制/粘贴所需的回溯线,并做到这一点:
ex_traceback = ['line 1', 'line 2', ...] for line in ex_traceback: print(line)
利润!
这个答案build立在上面的优秀。
在大多数应用程序中,您不会直接调用logging.exception(e)。 很可能你已经为你的应用程序或模块定义了特定的自定义logging器,如下所示:
# Set the name of the app or module my_logger = logging.getLogger('NEM Sequencer') # Set the log level my_logger.setLevel(logging.INFO) # Let's say we want to be fancy and log to a graylog2 log server graylog_handler = graypy.GELFHandler('some_server_ip', 12201) graylog_handler.setLevel(logging.INFO) my_logger.addHandler(graylog_handler)
在这种情况下,只需使用logging器来调用exception(e)就像这样:
try: 1/0 except Exception, e: my_logger.exception(e)
如果你可以处理额外的依赖关系然后使用twisted.log,你不必显式地logging错误,并且它将整个追踪和时间返回到文件或stream。
一个干净的方法是使用format_exc()
,然后parsing输出以获得相关部分:
from traceback import format_exc try: 1/0 except Exception: print 'the relevant part is: '+format_exc().split('\n')[-2]
问候