Como posso registrar meus erros do Python?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Como posso registrar meus erros do Python?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Use logging.exception
de dentro do except:
manipulador / bloco para registrar a exceção atual junto com as informações de rastreamento, anexadas com uma mensagem.
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
Agora, olhando para o arquivo de log /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')
precisará escreverlogger.exception('...')
para que isso funcione ...As
exc_info
opções de uso podem ser melhores, permanece aviso ou título do erro:fonte
exc_info=
kwarg é chamado; obrigado!logging.exception
Meu trabalho recentemente me encarregou de registrar todas as tracebacks / exceções do nosso aplicativo. Tentei várias técnicas que outros haviam publicado on-line, como a acima, mas decidiram por uma abordagem diferente. Substituindo
traceback.print_exception
.Eu tenho um artigo em http://www.bbarrows.com/ Isso seria muito mais fácil de ler, mas eu vou colá-lo aqui também.
Quando encarregado de registrar todas as exceções que nosso software pode encontrar na natureza, tentei várias técnicas diferentes para registrar nossos rastreamentos de exceção em python. No começo, pensei que o gancho de exceção do sistema python, sys.excepthook, seria o lugar perfeito para inserir o código de log. Eu estava tentando algo parecido com:
Isso funcionou para o thread principal, mas logo descobri que o my sys.excepthook não existiria em nenhum novo thread iniciado pelo meu processo. Esse é um problema enorme, porque quase tudo acontece nos threads deste projeto.
Depois de pesquisar no Google e ler muita documentação, as informações mais úteis que encontrei foram do rastreador do Python Issue.
O primeiro post no tópico mostra um exemplo de trabalho que
sys.excepthook
NÃO persiste nos tópicos (como mostrado abaixo). Aparentemente, esse é um comportamento esperado.As mensagens neste tópico do Python Issue realmente resultam em 2 hacks sugeridos. Subclasse
Thread
e agrupe o método run em nossa própria tentativa, exceto o bloco para capturar e registrar exceções ou patch de macacothreading.Thread.run
para executar em sua própria tentativa, exceto bloquear e registrar as exceções.O primeiro método de subclassificação
Thread
parece-me menos elegante em seu código, pois você teria que importar e usar suaThread
classe personalizada EM TODA PARTE QUE QUISER para ter um encadeamento de log. Isso acabou sendo um aborrecimento, porque eu tive que pesquisar em toda a nossa base de códigos e substituir tudo normalThreads
por esse costumeThread
. No entanto, ficou claro o que issoThread
estava fazendo e seria mais fácil para alguém diagnosticar e depurar se algo desse errado com o código de log personalizado. Um encadeamento de registro de custódia pode se parecer com o seguinte:O segundo método de aplicação de patches de macacos
threading.Thread.run
é bom, porque eu poderia executá-lo uma vez logo após__main__
e instrumentar meu código de log em todas as exceções. O patch do macaco pode ser irritante para a depuração, pois altera a funcionalidade esperada de algo. O patch sugerido do rastreador do Python Issue foi:Somente quando comecei a testar meu log de exceção, percebi que estava fazendo tudo errado.
Para testar eu tinha colocado um
em algum lugar do meu código. No entanto, agrupar um método que chamou esse método foi uma tentativa, exceto o bloco que imprimiu o retorno e engoliu a exceção. Isso foi muito frustrante porque vi o traceback ser impresso no STDOUT, mas não sendo registrado. Decidi então que um método muito mais fácil de registrar os tracebacks era apenas corrigir o método que todo o código python usa para imprimir os tracebacks, traceback.print_exception. Acabei com algo semelhante ao seguinte:
Esse código grava o traceback em um buffer de string e o registra no log de erro. Eu tenho um manipulador de log personalizado que configura o logger 'customLogger' que pega os logs no nível de ERRO e os envia para casa para análise.
fonte
add_custom_print_exception
não parece estar no site ao qual você vinculou e, em vez disso, há um código final bem diferente lá. Qual deles você diria que é melhor / mais final e por quê? Obrigado!logger.error(traceback.format_tb())
(ou format_exc () se você quiser as informações da exceção também).Você pode registrar todas as exceções não capturadas no thread principal atribuindo um manipulador
sys.excepthook
, talvez usando oexc_info
parâmetro das funções de log do Python :Se o seu programa usar threads, no entanto, observe que os threads criados usando não
threading.Thread
serão acionados quando ocorrer uma exceção não capturada dentro deles, conforme observado no Problema 1230540 no rastreador de problemas do Python. Alguns hacks foram sugeridos para contornar essa limitação, como a correção de macacos para substituir por um método alternativo que agrupa o original em um bloco e chama de dentro do bloco. Como alternativa, você pode apenas quebrar manualmente o ponto de entrada de cada um dos seus threads em / você mesmo.sys.excepthook
Thread.__init__
self.run
run
try
sys.excepthook
except
try
except
fonte
As mensagens de exceção não capturadas vão para STDERR; portanto, em vez de implementar seu log no próprio Python, você pode enviar o STDERR para um arquivo usando qualquer shell que esteja usando para executar seu script Python. Em um script Bash, você pode fazer isso com o redirecionamento de saída, conforme descrito no guia BASH .
Exemplos
Anexe erros ao arquivo, outra saída ao terminal:
Sobrescreva o arquivo com as saídas STDOUT e STDERR intercaladas:
fonte
O que eu estava procurando:
Vejo:
fonte
Você pode obter o rastreamento usando um registrador, em qualquer nível (DEBUG, INFO, ...). Observe que
logging.exception
, usando , o nível é ERRO.EDITAR:
Isso funciona também (usando python 3.6)
fonte
Aqui está uma versão que usa sys.excepthook
fonte
{traceback.format_exc()}
vez de{traceback.format_tb(stack)}
?talvez não seja tão estiloso, mas mais fácil:
fonte
Aqui está um exemplo simples, retirado da documentação do python 2.6 :
fonte