регистрация трассировки Python только в режиме отладки

1

В настоящее время я загружаю регистратор python следующим образом:

import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("myprogram")

и использовать его, например, так:

[...]
except FileNotFoundError:
    log.exception("could not open configuration file")
    sys.exit(1)

Тем не менее, это всегда будет печатать трассировку вместе с сообщением об ошибке:

ERROR:myprogram:could not open configuration file
Traceback (most recent call last):
[...]
FileNotFoundError: [Errno 2] No such file or directory: 
'not/existing/file.yml'

Я не хочу, чтобы трассировка в нормальном выходе ошибки. Вместо этого он должен печатать только мое сообщение об ошибке и информацию об исключении ("Нет такого файла...").

Каков рекомендуемый способ показа трассировки только тогда, когда loglevel установлен в logging.DEBUG?

Теги:
logging

2 ответа

2
Лучший ответ

Я бы использовал комбинацию exc_info и .getEffectiveLevel:

try:
    ...
except FileNotFoundError as ex:
   logger.error(ex, exc_info=log.getEffectiveLevel() == logging.DEBUG)

Таким образом, само исключение (FileNotFoundError) всегда регистрируется, но stacktrace будет регистрироваться только в том случае, если уровень журнала отлаживается.

  • 0
    В итоге я определил вспомогательную функцию следующим образом: def err(*args, **kwargs): log.error(*args, exc_info=log.getEffectiveLevel() == logging.DEBUG, **kwargs) делает именно то, что я хочу, спасибо!
3

exc_info=True исключение на уровне DEBUG и установите exc_info=True. logger.exception() по существу является logger.error(..., exc_info=True), но вы можете регистрировать трассировки исключений на любом уровне:

log.debug("could not open configuration file", exc_info=True)

Это опция exc_info которая важна; из документации:

Если exc_info не оценивается как false, это приводит к добавлению информации о исключении в сообщение регистрации. Если используется кортеж исключений (в формате, возвращаемом sys.exc_info()) или экземпляр исключения, он используется; в противном случае sys.exc_info() чтобы получить информацию об исключении.

Возможно, вы захотите использовать печать (для stdout или stderr) для связи с конечным пользователем:

except FileNotFoundError as e:
    log.debug("could not open configuration file", exc_info=True)
    print("Could not open configuration file:", e.strerror, file=sys.stderr)
    sys.exit(1)

Я включил сообщение об ошибке системы в выходной файл без представления FileNotFoundError(...).

Если вы используете парсер для командной строки, например argparse или click, тогда используйте API обратной связи с пользователями (который обычно также включает в себя выход).

Вы также можете сделать модуль протоколирования для создания сообщений на уровне пользователя, но если вы хотите, чтобы один вызов журнала вызывал отладочные трассировки в файле и удобный для пользователя вывод на консоли, вам нужно будет настроить отдельные обработчики для этих целей -cases с обработчиком консоли с помощью пользовательского Formatter() класса для переопределения formatException() метода, чтобы изменить, как показаны исключения. Гораздо проще и понятнее отделять протоколирование и связь с конечным пользователем.

  • 0
    хорошо, у меня сложилось неверное впечатление, что модуль журналирования снимет именно эту нагрузку с программиста. Я действительно использую argparse, который я должен использовать здесь для обработки этой конкретной ошибки, но у меня есть больше мест в программе, где мне это нужно. Большое спасибо!
  • 0
    @SebastianStark: ведение журнала может, в некотором роде, позаботиться об этом, но тогда вам нужно будет настроить дополнительный обработчик, который показывает только сообщения конечного пользователя, и использовать собственный подкласс Formatter чтобы изменить способ включения информации об исключениях в вывод , Вместо этого я обычно просто использую то, что изложил в своем ответе.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню