Python 如何记录带堆栈跟踪(Stack Trace)的错误日志?
记录完整异常堆栈:except 块中用 logging.exception() 或 logger.error(..., exc_info=True);主线程未捕获异常可用 sys.excepthook 处理,线程与异步任务另配。本文给出标准写法与最佳实践。
标准写法:在 except 块里调 logger.exception("描述")——自动附加完整堆栈;等价写法是 logger.error("...", exc_info=True)。
基本用法
import logging
logger = logging.getLogger(__name__)
try:
risky_operation()
except Exception:
logger.exception("risky_operation 执行失败") # 自动带堆栈
# 等价于 logger.error("...", exc_info=True)
输出包含完整 traceback:哪一行、调用链、异常类型与消息。
三种场景
# 1. except 块内(最常用)
except ValueError:
logger.exception("参数校验失败")
# 2. 显式传异常对象(此处仍在 except 内;块外使用需另行保存对象)
except Exception as e:
logger.error("失败", exc_info=e) # Python 3.5+ 支持直接传异常对象
# 3. 捕获未处理异常(程序兜底)
import sys
def handle_uncaught(exc_type, exc_value, exc_tb):
logger.critical("未捕获异常", exc_info=(exc_type, exc_value, exc_tb))
sys.excepthook = handle_uncaught
# 仅覆盖主线程未捕获异常;线程用 threading.excepthook,异步任务需事件循环/任务错误处理
以上 except 示例是片段,需放在对应 try 后。stack_info=True 记录当前调用栈,不等同于已发生异常的 traceback。
常见问题(FAQ)
Q:exception() 是什么级别? ERROR 级。
Q:exc_info=True 在非 except 块中有效吗? 无效——没有正在处理的异常时输出 NoneType: None。