如何记录Python错误及调试信息?

756 投票
17 回答
679387 浏览
提问于 2025-04-16 12:59

我正在用 logging.error 把 Python 的错误信息打印到一个日志文件里:

import logging
try:
    1/0
except ZeroDivisionError as e:
    logging.error(e)  # ERROR:root:division by zero

有没有办法打印出比错误字符串更详细的信息,比如出错的行号或者调用堆栈的信息,这样会更好。

17 个回答

220

关于 logging.exception 有一个很不错的特点,SiggyF 的回答没有提到,那就是你可以传入任意的消息,日志记录依然会显示完整的错误追踪信息和所有异常的细节:

import logging
try:
    1/0
except ZeroDivisionError:
    logging.exception("Deliberate divide by zero traceback")

在最近版本的默认设置下,日志记录的行为是将错误信息打印到 sys.stderr,效果如下:

>>> import logging
>>> try:
...     1/0
... except ZeroDivisionError:
...     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
274

使用 exc_info 选项可能会更好,这样你可以选择错误的级别(如果你使用 exception,它总是会被标记为 error 级别):

try:
    # do something here
except Exception as e:
    logging.critical(e, exc_info=True)  # log exception info at CRITICAL log level
1153

logger.exception 这个方法会在错误信息旁边输出一个堆栈跟踪。

举个例子:

import logging
try:
    1/0
except ZeroDivisionError:
    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 Cheque 提到,“要注意,在 Python 3 中,你必须在 except 语句块里调用 logging.exception 方法。如果你在其他地方调用这个方法,可能会出现奇怪的错误。文档里有提醒这一点。”

撰写回答