¿Cómo se generan excepciones no capturadas a través del logging
módulo en lugar de hacerlo stderr
?
Me doy cuenta de que la mejor manera de hacer esto sería:
try:
raise Exception, 'Throwing a boring exception'
except Exception, e:
logging.exception(e)
Pero mi situación es tal que sería realmente agradable si logging.exception(...)
se invocara automáticamente cada vez que no se detectara una excepción.
python
logging
exception-handling
Jacob Marble
fuente
fuente
Respuestas:
Como señaló Ned,
sys.excepthook
se invoca cada vez que se genera una excepción y no se detecta. La implicación práctica de esto es que en su código puede anular el comportamiento predeterminado desys.excepthook
hacer lo que quiera (incluido el usologging.exception
).Como ejemplo de hombre de paja:
Anular
sys.excepthook
:Comete un error de sintaxis obvio (omita los dos puntos) y obtenga información de error personalizada:
Para obtener más información acerca de
sys.excepthook
, lea los documentos .fuente
type
como argumento de función, aunque los IDE se quejarán por ocultar lo globaltype
(al igual que usarlovar self = this
en Javascript). Realmente no importa a menos que necesite acceder altype
objeto dentro de su función, en cuyo caso puede usarlotype_
como argumento.sys.excepthook
NO se llama cuando se genera una excepción. Se llama cuando el programa va a terminar debido a una excepción no detectada, que no puede suceder más de una vez.Aquí hay un pequeño ejemplo completo que también incluye algunos otros trucos:
Ignorar KeyboardInterrupt para que un programa de consola de Python pueda salir con Ctrl + C.
Confíe completamente en el módulo de registro de Python para formatear la excepción.
Utilice un registrador personalizado con un controlador de ejemplo. Este cambia la excepción no controlada para ir a stdout en lugar de stderr, pero puede agregar todo tipo de controladores en este mismo estilo al objeto registrador.
fuente
logger.critical()
dentro del controlador de excepción, ya que una excepción no detectada es bastante crítica, diría.logging.basicConfig(level=logging.DEBUG, filename="debug.log", format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
pero no me ayudó.El método
sys.excepthook
se invocará si no se detecta una excepción: http://docs.python.org/library/sys.html#sys.excepthookfuente
type
a la instancia?sys.excepthook
?Por qué no:
Aquí está la salida
sys.excepthook
como se ve arriba:Aquí está la salida con el
sys.excepthook
comentario:La única diferencia es que la primera tiene
ERROR:root:Unhandled exception:
al principio de la primera línea.fuente
sys.stderr
.Para construir sobre la respuesta de Jacinda, pero usando un objeto logger:
fuente
functools.partial()
lugar de lambda. Ver: docs.python.org/2/library/functools.html#functools.partialEnvuelva la llamada de entrada de la aplicación en un
try...except
bloque para que pueda capturar y registrar (y quizás volver a subir) todas las excepciones no detectadas. Por ejemplo, en lugar de:Hacer esto:
fuente
Tal vez podría hacer algo en la parte superior de un módulo que redirija stderr a un archivo y luego registrar ese archivo en la parte inferior
fuente
Aunque la respuesta de @ gnu_lorien me dio un buen punto de partida, mi programa falla en la primera excepción.
Llegué con una solución personalizada (y / o mejorada), que registra silenciosamente Excepciones de funciones decoradas
@handle_error
.fuente
Para responder la pregunta del Sr.Zeus discutida en la sección de comentarios de la respuesta aceptada, utilizo esto para registrar excepciones no capturadas en una consola interactiva (probada con PyCharm 2018-2019). Descubrí
sys.excepthook
que no funciona en un shell de Python, así que busqué más y descubrí que podía usarlosys.exc_info
. Sin embargo,sys.exc_info
no toma argumentos a diferencia de lossys.excepthook
que toma 3 argumentos.Aquí, uso ambos
sys.excepthook
ysys.exc_info
para registrar ambas excepciones en una consola interactiva y un script con una función de contenedor. Para adjuntar una función de enlace a ambas funciones, tengo dos interfaces diferentes dependiendo de si se dan argumentos o no.Aquí está el código:
La configuración de registro se puede encontrar en la respuesta de gnu_lorien.
fuente
En mi caso (usar
python 3
) cuando uso la respuesta de @Jacinda, el contenido del rastreo no se imprimió. En su lugar, sólo se imprime el objeto en sí mismo:<traceback object at 0x7f90299b7b90>
.En cambio hago:
fuente