python中异常与日志结合的核心是确保错误可追溯、可定位、可复盘,关键是在合适位置用logging.exception()记录含完整堆栈的异常信息,并按场景分级(error/warning/info)记录,同时补充请求id、用户id等上下文。

Python中把异常和日志结合使用,核心是让错误可追溯、可定位、可复盘。关键不是“捕获所有异常”,而是“在合适的位置记录有意义的信息”。
用logging.exception()代替print(e)或str(e)
这是最常见也最容易被忽略的一步。当异常发生时,直接调用logging.exception()会自动记录异常类型、消息和完整堆栈(traceback),比手动logging.error(str(e))强得多。
-
正确写法:在
except块中直接写logging.exception("用户登录失败"),无需额外参数 -
错误写法:
logging.error(f"登录失败: {e}")——丢失堆栈,无法定位到哪一行出错 - 注意:
exception()只能在异常上下文中调用(即except块内),否则不会输出traceback
按场景分级记录:error、warning、info要各司其职
不是所有异常都该记为ERROR。日志级别混乱会导致真正的问题被淹没。
- ERROR:不可恢复的故障,比如数据库连接中断、关键API调用失败且无备选方案
- WARNING:可恢复但需关注的情况,比如第三方服务超时后走降级逻辑,或用户输入格式不规范但已做容错
-
INFO:不记录异常本身,但可记录“异常已被处理”的事实,例如
logging.info("支付回调重复,已忽略")
补充上下文,别只记“发生了什么”,还要记“谁/在哪/为什么”
光有堆栈不够。生产环境排查时,常需要知道请求ID、用户ID、接口路径、参数摘要等。
立即学习“Python免费学习笔记(深入)”;
- extra参数注入上下文:
logging.exception("订单创建失败", extra={"order_id": oid, "user_id": uid}) - LoggerAdapter或
Filter实现请求级上下文自动注入(如Web框架中绑定request_id)
避免日志爆炸:异常循环记录与重复捕获
同一异常在多层try-except中反复记录,既浪费IO,又干扰问题定位。
- raise),就不要记录
- except Exception:吞掉异常却不记录也不处理——这是静默失败,比报错更危险
- json.JSONDecodeError),明确捕获具体类型,避免宽泛捕获掩盖真实问题
异常日志不是越多越好,而是要每一条都有明确目的和可操作性。记录得清楚,才能查得快、修得准。










