Python生产环境报错时如何自动记录相关局部变量排查KeyError问题
可行的三种实现方案
方案1:全局异常钩子自动捕获栈上下文
所有未捕获异常触发时自动打印对应栈帧的局部变量,不需要修改业务代码:
import sys import logging from types import FrameType logger = logging.getLogger(__name__) # 配置logger输出格式、handler等省略,按生产环境现有配置即可 def custom_excepthook(exc_type, exc_value, exc_tb): # 先输出标准异常栈 logger.critical("Uncaught exception occurred", exc_info=(exc_type, exc_value, exc_tb)) # 遍历栈帧提取局部变量 frame: FrameType = exc_tb.tb_frame while frame: logger.critical(f"=== Local variables at {frame.f_code.co_filename}:{frame.f_lineno} in {frame.f_code.co_name} ===") for var_name, var_val in frame.f_locals.items(): try: val_repr = repr(var_val) # 生产环境可调整截断长度,避免日志过大 val_repr = val_repr[:2000] + "[TRUNCATED]" if len(val_repr) > 2000 else val_repr logger.critical(f" {var_name} = {val_repr}") except Exception as e: logger.critical(f" {var_name} = <repr failed: {repr(e)}>") frame = frame.f_back sys.excepthook = custom_excepthook
触发KeyError时你可以直接在日志里找到报错行所在栈帧的res变量完整内容,不需要提前插入日志代码。
注意:异步应用的协程异常不会被
sys.excepthook捕获,需要额外配置异步事件循环的异常处理器。
方案2:封装响应解析通用方法
仅针对HTTP响应解析场景做统一处理,侵入性低:
import logging import requests logger = logging.getLogger(__name__) def safe_parse_response(res: requests.Response): try: json_data = res.json() return json_data["data"] except (KeyError, ValueError) as e: # 报错时自动输出完整响应信息 logger.error( "Response parse failed, status=%d, raw content=%s", res.status_code, res.text[:2000], exc_info=True ) # 保留原有异常抛出逻辑,不影响业务流程 raise
原有业务代码只需要把res.json()["data"]替换为safe_parse_response(res)即可,所有解析异常都会自动记录完整响应内容。
方案3:自定义日志过滤器注入上下文
如果需要给所有请求相关日志统一加上下文,可以使用logging的过滤器实现:
class RequestContextFilter(logging.Filter): def filter(self, record): # 从当前上下文(比如threadlocal、async context var)获取最近的请求响应对象 current_res = getattr(request_context, "current_res", None) if current_res: record.res_status = current_res.status_code record.res_content = current_res.text[:2000] return True # 给logger添加过滤器 logger.addFilter(RequestContextFilter()) # 日志格式里可以直接用添加的字段:%(res_status)s %(res_content)s
生产环境注意事项
- 所有打印逻辑需要添加敏感信息脱敏规则,避免token、用户隐私等数据泄露到日志中
- 严格控制内容打印长度,避免大响应体导致日志文件异常膨胀
- 可根据业务需求过滤不需要打印的变量,减少无效日志输出
内容的提问来源于stack exchange,提问作者Aron
相关产品推荐
相关产品推荐

