logging.exception() 必须在 except 块中调用以获取异常上下文并输出完整 traceback,离开该块则静默丢弃堆栈;logging.error() 需显式传 exc_info=true 才记录 traceback,否则仅输出消息。

因为 logging.exception() 自动绑定当前异常上下文并强制输出完整 traceback,而 logging.error() 默认不带堆栈——漏掉 exc_info=True 参数,日志就只剩一句“出错了”,线上根本没法定位问题。
logging.exception() 必须在 except 块里调用
它依赖 sys.exc_info() 获取当前异常三元组(type, value, traceback)。一旦离开 except 块,这个上下文就被清空,logging.exception() 会静默丢弃 traceback,只打一条空 error 日志。
- ✅ 正确:在
except ValueError as e:内直接调用logging.exception("解析失败") - ❌ 错误:把异常对象
e传给另一个函数,再在函数里调用logging.exception()—— 此时已不在异常上下文中 - ⚠️ 注意:
logging.exception()本身不接受exc_info参数;传了会报TypeError
logging.error() 漏掉 exc_info=True 就等于没记录异常
logging.error("请求超时") 和 logging.error("请求超时", exc_info=True) 看似只差一个参数,但效果天壤之别:前者只输出时间、级别、消息;后者才附上完整的 traceback,包括文件名、行号、调用链。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 常见错误:写成
logger.error("failed", e)—— 这是在做字符串格式化,e被当成了%s占位符的值,不是异常上下文 - 更糟的是:
logger.error("failed", exc_info=e)也不对,exc_info应为True或三元组,不能直接传异常实例 - 如果需要动态控制是否打堆栈(比如某些环境只记录摘要),用
logging.error("msg", exc_info=should_log_traceback)
formatter 里 %(exc_text)s 不是万能的
很多人配了 %(exc_text)s 就以为万事大吉,结果日志里永远看不到堆栈——因为这个字段只在日志 level ≥ ERROR 且 exc_info 非空时才生效。
- 必须确保 handler 的
level≤ERROR,否则logging.exception()发出的日志被过滤掉 -
%(asctime)s默认不带毫秒,高并发下多条日志时间戳一样,建议改用%(asctime)s.%(msecs)03d -
%(exc_text)s输出的 traceback 不自动缩进,若需对齐,得自定义Formatter子类处理
真正容易被忽略的是:即使你用了 logging.exception(),如果 root logger 没配任何 handler(比如忘了调用 basicConfig() 或手动 addHandler),日志会彻底消失,连 warning 都不报。线上服务启动时务必检查 logger.handlers 是否非空。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










