Python日志配置:控制台屏蔽Traceback,文件保留异常信息
单个Logger实现不同Handler的exc_info差异化输出
现有配置
config.conf
version: 1 formatters: simple: format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' filters: warnings_and_below: "()": log.filter_maker level: WARNING sense: below errors_and_above: "()": log.filter_maker level: ERROR sense: above handlers: outconsole: class: logging.StreamHandler level: INFO formatter: simple filters: [warnings_and_below] stream: ext://sys.stdout errconsole: class: logging.StreamHandler level: WARNING formatter: simple filters: [errors_and_above] stream: ext://sys.stderr file_handler: class: logging.FileHandler level: DEBUG formatter: simple filename: info.log encoding: utf8 mode: w root: level: DEBUG handlers: [file_handler, outconsole, errconsole] propagate: no
log.py
import logging.config import logging import yaml def filter_maker(level, sense): level = getattr(logging, level) # 获取日志级别对应的数值 if sense == 'below': # 只允许级别小于等于阈值的日志通过 def filter(record): return record.levelno <= level else: # 只允许级别大于等于阈值的日志通过 def filter(record): return record.levelno >= level return filter with open("config.conf", "r") as f: config = yaml.safe_load(f.read()) logging.config.dictConfig(config) Logger = logging.getLogger(__name__) Logger.error("Some error") Logger.error("Some error", exc_info=True)
需求
执行最后两行Logger.error语句时:
errconsole处理器始终以exc_info=False输出(不显示Traceback)file_handler处理器始终以exc_info=True输出(保留异常信息)
解答:完全可以用单个Logger实现,无需配置第二个
核心就是通过自定义过滤器或者处理器,让不同的Handler对日志记录里的exc_info属性做不同处理,不用搞两个Logger这么麻烦。
方式一:给errconsole加专属过滤器,直接关掉exc_info
- 在
log.py里新增一个过滤器函数:
def suppress_exc_info_filter(record): # 把exc_info设为False,让这个Handler不输出Traceback record.exc_info = False record.exc_text = None return True
- 修改
config.conf的过滤器和errconsole配置:
filters: # 保留原有两个过滤器 warnings_and_below: "()": log.filter_maker level: WARNING sense: below errors_and_above: "()": log.filter_maker level: ERROR sense: above # 新增屏蔽exc_info的过滤器 suppress_exc: "()": log.suppress_exc_info_filter handlers: errconsole: class: logging.StreamHandler level: WARNING formatter: simple filters: [errors_and_above, suppress_exc] # 添加新过滤器 stream: ext://sys.stderr
方式二:自定义Handler类,输出时临时屏蔽Traceback
- 在
log.py里定义自定义Handler:
class NoTracebackStreamHandler(logging.StreamHandler): def emit(self, record): # 先保存原有的exc_info属性,输出后恢复,不影响其他Handler original_exc_info = record.exc_info original_exc_text = record.exc_text # 临时关掉exc_info record.exc_info = False record.exc_text = None # 调用父类方法输出日志 super().emit(record) # 恢复原属性 record.exc_info = original_exc_info record.exc_text = original_exc_text
- 修改
config.conf中errconsole的class配置:
handlers: errconsole: class: log.NoTracebackStreamHandler # 替换为自定义Handler level: WARNING formatter: simple filters: [errors_and_above] stream: ext://sys.stderr
两种方法都能实现单个Logger下,不同Handler分别控制是否显示Traceback的需求,没必要额外创建第二个Logger。
内容的提问来源于stack exchange,提问作者MattyOstrowsky
相关产品推荐
相关产品推荐

