最简单的禁用选项每个处理程序回溯输出是添加一个自定义的logging.Filter子类改变记录对象(而不是过滤掉记录)。
过滤器只需设置exc_info
记录在案None
:
class TracebackInfoFilter(logging.Filter):
"""Clear or restore the exception on log records"""
def __init__(self, clear=True):
self.clear = clear
def filter(self, record):
if self.clear:
record._exc_info_hidden, record.exc_info = record.exc_info, None
# clear the exception traceback text cache, if created.
record.exc_text = None
elif hasattr(record, "_exc_info_hidden"):
record.exc_info = record._exc_info_hidden
del record._exc_info_hidden
return True
and 在您的处理程序中添加该过滤器:
# do not display tracebacks in messages handled with this handler,
# by setting the traceback cache to a non-empty string:
handler_with_no_tracebacks.addFilter(TracebackInfoFilter())
However,处理程序不copy日志记录以及传递相同日志记录的任何其他处理程序later on还将忽略回溯的格式。所以你还需要配置任何other处理程序再次恢复信息:
for handler in logger.handlers:
if not any(isinstance(f, TracebackInfoFilter) for f in handler.filters):
handler.addFilter(TracebackInfoFilter(clear=False))
如果有人想禁用all回溯输出无处不在,那么向所有处理程序或记录器添加自定义过滤器可能会变得乏味。在这种情况下,另一个选择是注册一个自定义记录工厂logging.setLogRecordFactory()功能;只需设置exc_info
记录上的属性None
,无条件:
record_factory = logging.getLogRecordFactory()
def clear_exc_text(*args, **kwargs):
record = record_factory(*args, **kwargs)
record.exc_info = None
return record
logging.setLogRecordFactory(clear_exc_text)
请注意,默认工厂只是logging.LogRecord class,但上述函数尽力与任何已设置的自定义工厂配合使用。
当然,您也可以创建自己的Handler
子类,其中Handler.handle()设置和清除exc_info
属性:
class NoTracebackHandler(logging.Handler):
def handle(self, record):
info, cache = record.exc_info, record.exc_text
record.exc_info, record.exc_text = None, None
try:
super().handle(record)
finally:
record.exc_info = info
record.exc_text = cache