¿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.exceptiondesde 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_infoopciones de uso pueden ser mejores, sigue siendo advertencia o título de error:fuente
exc_info=se llama el kwarg; ¡Gracias!logging.exceptionMi 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.excepthookNO 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
Thready 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.runpara ejecutar en su propio intento, excepto bloquear y registrar las excepciones.El primer método de subclasificación
Threadme parece menos elegante en su código, ya que tendría que importar y usar suThreadclase 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 normalThreadscon esta costumbreThread. Sin embargo, estaba claro quéThreadestaba 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.runes 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_exceptionno 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_infopará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.Threadvoluntad no de disparosys.excepthookcuando 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.runcon unrunmétodo alternativo que envuelve el original en untrybloque y llamasys.excepthookdesde dentro delexceptbloque. Alternativamente, puede ajustar manualmente el punto de entrada para cada uno de sus hilos entry/exceptusted 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