Самый простой способ отключить для каждого обработчика вывод трассировки - добавить пользовательский 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
и добавить этот фильтр на ваш обработчик :
# 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())
Однако , обработчики не копируют записи журнала, и любой другой обработчик, которому передана та же запись журнала позже , также будет игнорировать форматирование трассировки.Поэтому вам также необходимо настроить любые другие обработчики для восстановления информации снова:
for handler in logger.handlers:
if not any(isinstance(f, TracebackInfoFilter) for f in handler.filters):
handler.addFilter(TracebackInfoFilter(clear=False))
Если кто-то хочет отключить все трассировочные выходы, везде, затем возможно добавлениенастраиваемый фильтр для всех обработчиков или регистраторов становится утомительным.В этом случае другой вариант - зарегистрировать пользовательскую фабрику записей с помощью функции 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