Я печатаю сообщения об исключениях Python в файл журнала с logging.error
:
import logging
try:
1/0
except ZeroDivisionError as e:
logging.error(e) # ERROR:root:division by zero
Можно ли напечатать более подробную информацию об исключении и коде, который его сгенерировал, чем просто строку исключения? Такие вещи, как номера строк или трассировки стека, были бы великолепны.
python
exception
logging
exception-handling
наверное на пляже
источник
источник
exception
Метод просто вызываетerror(message, exc_info=1)
. Как только вы перейдетеexc_info
к любому из методов ведения журнала из контекста исключения, вы получите трассировку.sys.excepthook
(см. Здесь ), чтобы избежать необходимости переносить весь код в try / кроме.except Exception:
потому что вы не используетеe
в любом случае;)e
при попытке интерактивно отладить ваш код. :) Вот почему я всегда включаю это.raise
в конец областиexcept
видимости. В противном случае работа продолжится, как будто все в порядке.Одна приятная вещь в том,
logging.exception
что ответ SiggyF не показывает, что вы можете передать произвольное сообщение, и при ведении журнала все равно будет отображаться полный возврат со всеми деталями исключения:По умолчанию (в последних версиях) ведение журнала только ошибок печати
sys.stderr
выглядит следующим образом:источник
''
если вы действительно не хотите печатать сообщение ... хотя функцию нельзя вызвать без хотя бы одного аргумента, так что вам придется что-то ему дать.Использование
exc_info
параметров может быть лучше, чтобы позволить вам выбрать уровень ошибки (если вы используетеexception
, он всегда будет наerror
уровне):источник
logging.fatal
ли метод в библиотеке журналов? Я только вижуcritical
.critical
, как иwarn
дляwarning
.квотирование
Теперь
traceback
можно использовать здесь.Используйте это в Python 2 :
Используйте это в Python 3 :
источник
ex_traceback
он из-ex.__traceback__
под Python 3, ноex_traceback
из-sys.exc_info()
под Python 2.Если вы используете простые журналы - все ваши записи журнала должны соответствовать этому правилу:
one record = one line
. Следуя этому правилу, вы можете использоватьgrep
и другие инструменты для обработки ваших файлов журналов.Но информация трассировки многострочная. Так что мой ответ - расширенная версия решения, предложенного выше zangw в этой теме. Проблема в том, что строки трассировки могут быть
\n
внутри, поэтому нам нужно проделать дополнительную работу, чтобы избавиться от окончаний этой строки:После этого (когда вы будете анализировать ваши журналы) вы можете скопировать / вставить необходимые строки трассировки из вашего файла журнала и сделать это:
Прибыль!
источник
Этот ответ основан на вышеупомянутых превосходных.
В большинстве приложений вы не будете вызывать logging.exception (e) напрямую. Скорее всего, вы определили специальный регистратор, специфичный для вашего приложения или модуля, например:
В этом случае просто используйте регистратор для вызова исключения (e), например:
источник
Вы можете регистрировать трассировку стека без исключения.
https://docs.python.org/3/library/logging.html#logging.Logger.debug
Пример:
источник
Немного декораторской обработки (очень слабо вдохновлено монадой Maybe и лифтингом). Вы можете безопасно удалять аннотации типа Python 3.6 и использовать более старый стиль форматирования сообщений.
fallible.py
Демо-версия:
Вы также можете изменить это решение, чтобы оно возвращало что-то более значимое, чем
None
изexcept
части (или даже сделать решение универсальным, указав это возвращаемое значение вfallible
аргументах).источник
В вашем модуле регистрации (если пользовательский модуль) просто включите stack_info.
источник
Если вы можете справиться с дополнительной зависимостью, тогда используйте twisted.log, вам не нужно явно регистрировать ошибки, а также он возвращает всю обратную трассировку и время в файл или поток.
источник
twisted
, это хорошая рекомендация, но этот ответ мало что дает. В нем не говорится, как использоватьtwisted.log
, и какие преимущества он имеет по сравнению сlogging
модулем из стандартной библиотеки, и не объясняется, что означает «вам не нужно явно регистрировать ошибки» .Чистый способ сделать это - использовать
format_exc()
и затем проанализировать вывод, чтобы получить соответствующую часть:С уважением
источник
.split('\n')[-2]
нужно сделать, это выбросить номер строки и обратную трассировку из результатаformat_exc()
- полезной информации, которую вы обычно хотите! Более того, это даже не делает хорошую работу этого ; если ваше сообщение об исключении содержит символ новой строки, то при таком подходе будет напечатана только последняя строка сообщения об исключении - это означает, что вы теряете класс исключения и большую часть сообщения об исключении поверх потери трассировки. -1.