Журнал Python: отключить трассировку стека - PullRequest
0 голосов
/ 09 февраля 2019

Есть ли простой способ отключить ведение журнала трассировки стека исключений в Python 3, либо в Handler, либо в Formatter?

Мне нужна трассировка стека в другом Handler, поэтому установка exc_info=False при вызове Logger не вариант.Есть ли более простой способ, чем просто определить мой собственный Formatter?

1 Ответ

0 голосов
/ 09 февраля 2019

Самый простой способ отключить для каждого обработчика вывод трассировки - добавить пользовательский 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...