¿Cómo puedo registrar mis errores de Python?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
¿Cómo puedo registrar mis errores de Python?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Use logging.exception
desde el except:
controlador / bloque para registrar la excepción actual junto con la información de rastreo, precedida por un mensaje.
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
Ahora mirando el archivo de registro /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')
usted, debe escribirlogger.exception('...')
para que esto funcione ...Las
exc_info
opciones de uso pueden ser mejores, sigue siendo advertencia o título de error:fuente
exc_info=
se llama el kwarg; ¡Gracias!logging.exception
Mi trabajo recientemente me encargó registrar todas las trazas / excepciones de nuestra aplicación. Probé numerosas técnicas que otros habían publicado en línea, como la anterior, pero me decidí por un enfoque diferente. Primordial
traceback.print_exception
.Tengo un escrito en http://www.bbarrows.com/ Eso sería mucho más fácil de leer, pero también lo pegaré aquí.
Cuando tuve la tarea de registrar todas las excepciones que nuestro software podría encontrar en la naturaleza, probé varias técnicas diferentes para registrar nuestros rastreos de excepciones de Python. Al principio pensé que el gancho de excepción del sistema python, sys.excepthook, sería el lugar perfecto para insertar el código de registro. Estaba intentando algo similar a:
Esto funcionó para el hilo principal, pero pronto descubrí que my sys.excepthook no existiría en ningún hilo nuevo que mi proceso comenzó. Este es un gran problema porque casi todo sucede en subprocesos en este proyecto.
Después de buscar en Google y leer mucha documentación, la información más útil que encontré fue del rastreador de problemas de Python.
La primera publicación en el hilo muestra un ejemplo funcional de que
sys.excepthook
NO persiste en los hilos (como se muestra a continuación). Aparentemente este es el comportamiento esperado.Los mensajes en este hilo de Python Issue realmente resultan en 2 hacks sugeridos. Puede subclasificar
Thread
y envolver el método de ejecución en nuestro propio intento, excepto el bloque para capturar y registrar excepciones o el parche de monothreading.Thread.run
para ejecutar en su propio intento, excepto bloquear y registrar las excepciones.El primer método de subclasificación
Thread
me parece menos elegante en su código, ya que tendría que importar y usar suThread
clase personalizada EN TODAS PARTES donde quisiera tener un hilo de registro. Esto terminó siendo una molestia porque tuve que buscar en toda nuestra base de código y reemplazar todo lo normalThreads
con esta costumbreThread
. Sin embargo, estaba claro quéThread
estaba haciendo esto y sería más fácil para alguien diagnosticar y depurar si algo salía mal con el código de registro personalizado. Un hilo de registro personalizado podría verse así:El segundo método de parchear mono
threading.Thread.run
es bueno porque podría ejecutarlo una vez justo después__main__
e instrumentar mi código de registro en todas las excepciones. Sin embargo, los parches de mono pueden ser molestos para depurar, ya que cambia la funcionalidad esperada de algo. El parche sugerido del rastreador de problemas de Python fue:No fue hasta que comencé a probar mi registro de excepciones cuando me di cuenta de que estaba haciendo todo mal.
Para probar había colocado un
en algún lugar de mi código Sin embargo, envolver un método que llamó a este método fue un intento, excepto el bloque que imprimió el rastreo y se tragó la excepción. Esto fue muy frustrante porque vi que el rastreo se traía impreso a STDOUT pero no se registraba. Entonces decidí que un método mucho más fácil de registrar los rastreos era simplemente parchear el método que todo el código de Python usa para imprimir los mismos rastreos, traceback.print_exception. Terminé con algo similar a lo siguiente:
Este código escribe el rastreo en un Búfer de cadena y lo registra en ERROR de registro. Tengo un controlador de registro personalizado que configura el registrador 'customLogger' que toma los registros de nivel de ERROR y los envía a casa para su análisis.
fuente
add_custom_print_exception
no parece estar en el sitio al que se vinculó, y en su lugar hay un código final bastante diferente allí. ¿Cuál dirías que es mejor / más final y por qué? ¡Gracias!logger.error(traceback.format_tb())
(o format_exc () si también desea la información de excepción).Puede registrar todas las excepciones no detectadas en el hilo principal asignando un controlador a
sys.excepthook
, quizás utilizando elexc_info
parámetro de las funciones de registro de Python :Si los hilos de los usos del programa, sin embargo, a continuación, tenga en cuenta que los hilos creados usando
threading.Thread
voluntad no de disparosys.excepthook
cuando se produce una excepción no capturada dentro de ellos, como se señala en Edición 1.230.540 de seguimiento de incidencias de Python. Se han sugerido algunos hacks para evitar esta limitación, como parches de monoThread.__init__
para sobrescribirself.run
con unrun
método alternativo que envuelve el original en untry
bloque y llamasys.excepthook
desde dentro delexcept
bloque. Alternativamente, puede ajustar manualmente el punto de entrada para cada uno de sus hilos entry
/except
usted mismo.fuente
Los mensajes de excepción no capturados van a STDERR, por lo que, en lugar de implementar su registro en Python, podría enviar STDERR a un archivo utilizando el shell que esté utilizando para ejecutar su script Python. En un script Bash, puede hacer esto con la redirección de salida, como se describe en la guía BASH .
Ejemplos
Agregue errores al archivo, otra salida al terminal:
Sobrescribir archivo con salida STDOUT y STDERR intercalada:
fuente
Lo que estaba buscando:
Ver:
fuente
Puede obtener el rastreo utilizando un registrador, en cualquier nivel (DEPURACIÓN, INFORMACIÓN, ...). Tenga en cuenta que usando
logging.exception
, el nivel es ERROR.EDITAR:
Esto también funciona (usando Python 3.6)
fuente
Aquí hay una versión que usa sys.excepthook
fuente
{traceback.format_exc()}
lugar de{traceback.format_tb(stack)}
?tal vez no tan elegante, pero más fácil:
fuente
Aquí hay un ejemplo simple tomado de la documentación de python 2.6 :
fuente