Python logging 修改单个handler的formatException后全handler生效问题
问题根因
这是Python logging 模块的默认设计逻辑,不是使用错误:
当日志事件携带异常信息时,第一个处理该日志的Formatter调用formatException生成异常文本后,会把结果缓存到LogRecord对象的exc_text属性中。后续处理同一条日志的其他Formatter会直接复用这个缓存的异常文本,不会再调用自己的formatException方法,因此所有异常输出都和第一个Handler(stream_handler2)的格式化结果一致。
解决方法
重写自定义Formatter类的format方法,每次处理日志前清空exc_text缓存,强制触发当前Formatter自己的formatException逻辑即可:
import logging, io, traceback class TermFormatter(logging.Formatter): def __init__(self, *args, stack_limit=1, **kwargs): super().__init__(*args, **kwargs) self.stack_limit = stack_limit def format(self, record): # 清空异常缓存,强制当前Formatter重新生成异常文本 record.exc_text = None return super().format(record) def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = io.StringIO() tb = ei[2] # See issues #9427, #1553375. Commented out for now. #if getattr(self, 'fullstack', False): # traceback.print_stack(tb.tb_frame.f_back, file=sio) traceback.print_exception(ei[0], ei[1], tb, self.stack_limit, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] if self.stack_limit ==0: return "Hello my friend!" else: return s
修改后运行测试代码,输出就会符合预期:
- F2格式的异常输出为自定义内容
Hello my friend! - F1格式的异常输出为长度限制为2的栈追踪
- F3格式的异常输出为默认全量栈追踪
内容的提问来源于stack exchange,提问作者hyamanieu
相关产品推荐
相关产品推荐

