В настоящее время я загружаю регистратор Python, как это:

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

И используя его e. грамм. как это:

[...]
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'

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

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

6
Sebastian Stark 23 Сен 2018 в 15:09

2 ответа

Лучший ответ

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

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

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

3
DeepSpace 23 Сен 2018 в 12:21

Вместо этого зарегистрируйте исключение на уровне 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 не считается ложным, это приводит к добавлению информации об исключении в сообщение журнала. Если предоставляется кортеж исключения (в формате, возвращаемом 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 обратной связи с пользователем (который обычно также включает в себя выход).

Вы можете заставить модуль ведения журнала создавать сообщения пользовательского уровня, но если вы хотите, чтобы один вызов регистратора производил удобные для отладки трассировки в файле и удобный вывод на консоль, у вас должен быть для настройки отдельных обработчиков для этих вариантов использования с обработчиком консоли с помощью настраиваемого Formatter() класс, чтобы переопределить { {X1}} метод, чтобы изменить способ отображения исключений. Просто разделить ведение журнала и общение с конечным пользователем намного проще и понятнее.

4
Martijn Pieters 23 Сен 2018 в 12:45