Как я могу регистрировать свои ошибки Python?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Как я могу регистрировать свои ошибки Python?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Используйте logging.exception
из except:
обработчика / блока для регистрации текущего исключения вместе с информацией трассировки, с добавлением сообщения.
import logging
LOG_FILENAME = '/tmp/logging_example.out'
logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
logging.debug('This message should go to the log file')
try:
run_my_stuff()
except:
logging.exception('Got exception on main handler')
raise
Теперь посмотрим на файл журнала /tmp/logging_example.out
:
DEBUG:root:This message should go to the log file
ERROR:root:Got exception on main handler
Traceback (most recent call last):
File "/tmp/teste.py", line 9, in <module>
run_my_stuff()
NameError: name 'run_my_stuff' is not defined
logger = logging.getLogger('yourlogger')
вами, вы должны написать,logger.exception('...')
чтобы это работало ...exc_info
Варианты использования могут быть лучше, остается предупреждение или название ошибки:источник
exc_info=
называется kwarg; Спасибо!logging.exception
Недавно моя работа поручила мне регистрировать все трассировки / исключения из нашего приложения. Я перепробовал множество техник, которые другие опубликовали в сети, например, выше, но остановился на другом подходе. Перекрытие
traceback.print_exception
.У меня есть запись на http://www.bbarrows.com/ Это было бы намного легче читать, но я также вставлю это сюда.
Когда мне было поручено записывать в журнал все исключения, с которыми наше программное обеспечение может столкнуться в дикой природе, я попробовал несколько различных методов для регистрации наших трассировок исключений Python. Сначала я подумал, что хук системных исключений python, sys.excepthook, будет идеальным местом для вставки кода регистрации. Я пытался что-то похожее на:
Это сработало для основного потока, но вскоре я обнаружил, что мой sys.excepthook не будет существовать ни в каких новых потоках, запущенных моим процессом. Это огромная проблема, потому что большинство всего происходит в потоках в этом проекте.
После поиска в Google и прочтения большого количества документации, самая полезная информация, которую я нашел, была от трекера Python Issue.
В первом сообщении в теме показан рабочий пример
sys.excepthook
НЕ сохраняющегося в потоках (как показано ниже). Видимо, это ожидаемое поведение.Сообщения в этом потоке Python Issue действительно приводят к двум предложенным хаки. Либо создайте подкласс
Thread
и оберните метод run в нашем собственном try, кроме block, чтобы перехватывать и регистрировать исключения, либо monkey patchthreading.Thread.run
для запуска в вашем собственном try, кроме block и регистрировать исключения.Первый метод создания подклассов
Thread
мне кажется менее элегантным в вашем коде, так как вам придется импортировать и использовать свой собственныйThread
класс ВЕЗДЕ, где вы хотите создать поток ведения журнала. Это оказалось хлопотным, потому что мне пришлось искать всю нашу кодовую базу и заменять все обычноеThreads
на этотThread
. Тем не менее, было ясно, что этоThread
делает, и кому-то будет проще диагностировать и отлаживать, если что-то пойдет не так с пользовательским кодом регистрации. Обычная ветка может выглядеть так:Второй способ исправления обезьяны
threading.Thread.run
хорош, потому что я мог бы просто запустить его один раз сразу__main__
и обработать код регистрации во всех исключениях. Патч обезьяны может быть раздражающим для отладки, поскольку он изменяет ожидаемую функциональность чего-либо. Предлагаемый патч от трекера Python Issue:Только когда я начал тестировать свою регистрацию исключений, я понял, что поступаю неправильно.
Для проверки я поместил
где-то в моем коде. Однако перенос метода, вызвавшего этот метод, был попыткой, за исключением блока, который распечатывал трассировку и проглотил исключение. Это очень расстраивало, потому что я видел, как трассировку принесли в STDOUT, но не регистрировали. Тогда я решил, что гораздо более простой метод регистрации трассировок заключается в том, чтобы просто обезопасить патч от метода, который весь код Python использует для печати самих трассировок, traceback.print_exception. Я закончил с чем-то похожим на следующее:
Этот код записывает трассировку в String Buffer и записывает его в журнал ERROR. У меня есть собственный обработчик журналов, который настраивает регистратор 'customLogger', который берет журналы уровня ОШИБКИ и отправляет их домой для анализа.
источник
add_custom_print_exception
не похоже на сайт, на который вы ссылаетесь, и вместо этого есть несколько иной конечный код. Какой из них вы бы назвали лучшим / более окончательным и почему? Спасибо!logger.error(traceback.format_tb())
(или format_exc (), если вы тоже хотите получить информацию об исключении).Вы можете регистрировать все неперехваченные исключения в главном потоке, назначив обработчик
sys.excepthook
, возможно, используяexc_info
параметр функций журналирования Python :Однако, если ваша программа использует потоки, обратите внимание, что потоки, созданные с использованием
threading.Thread
, не будут срабатывать,sys.excepthook
когда внутри них возникает неперехваченное исключение, как отмечено в выпуске 1230540 в системе отслеживания проблем Python. Там было предложено несколько хаков, чтобы обойти это ограничение, например, monkey-patchingThread.__init__
для перезаписиself.run
альтернативнымrun
методом, который оборачивает оригинал вtry
блок и вызываетsys.excepthook
изнутриexcept
блока. Кроме того, вы можете просто вручную обернуть точку входа для каждого из ваших потоков вtry
/except
себя.источник
Необработанные сообщения об исключениях отправляются в STDERR, поэтому вместо того, чтобы осуществлять регистрацию в самом Python, вы можете отправить STDERR в файл, используя любую оболочку, которую вы используете для запуска скрипта Python. В сценарии Bash это можно сделать с помощью перенаправления вывода, как описано в руководстве по BASH .
Примеры
Добавить ошибки в файл, другой вывод в терминал:
Перезаписать файл с чередованием вывода STDOUT и STDERR:
источник
Что я искал:
Видеть:
источник
Вы можете получить трассировку с помощью регистратора на любом уровне (DEBUG, INFO, ...). Обратите внимание, что при использовании
logging.exception
, уровень является ОШИБКА.РЕДАКТИРОВАТЬ:
Это тоже работает (с использованием Python 3.6)
источник
Вот версия, которая использует sys.excepthook
источник
{traceback.format_exc()}
вместо{traceback.format_tb(stack)}
?возможно не так стильно, но проще
источник
Вот простой пример, взятый из документации по Python 2.6 :
источник