2010-12-22 10 views
46

¿Cómo puedo registrar una excepción en Python?¿Cómo registrar la excepción de Python?

He mirado en algunas opciones y descubrí que puedo tener acceso a los detalles reales de excepción mediante este código:

import sys 
import traceback 

try: 
    1/0 
except: 
    exc_type, exc_value, exc_traceback = sys.exc_info() 
    traceback.print_exception(exc_type, exc_value, exc_traceback) 

me gustaría obtener alguna manera la cadena print_exception() tiros a la salida estándar para que pueda registrarlo .

+3

Al menos 'raise' (sin argumento, por lo que se conserva la stracktrace) después del registro, de lo contrario se traga la excepción si lently. – delnan

+1

Siempre debe indicar explícitamente la excepción que está tratando de detectar: ​​'excepto NameError como e', por ejemplo. Eso evitará que capture cosas como 'KeyboardInterrupt' * y * le dará una referencia al objeto de excepción, que puede estudiar para obtener más detalles. – katrielalex

Respuesta

48

Para responder a su pregunta, puede obtener la versión de serie de print_exception() utilizando el traceback.format_exception() función. Devuelve el mensaje de seguimiento como una lista de cadenas en lugar de imprimirlo en stdout, para que pueda hacer lo que quiera con él. Por ejemplo:

import sys 
import traceback 

try: 
    asdf 
except NameError: 
    exc_type, exc_value, exc_traceback = sys.exc_info() 
    lines = traceback.format_exception(exc_type, exc_value, exc_traceback) 
    print ''.join('!! ' + line for line in lines) # Log it or whatever here 

Esta muestra:

!! Traceback (most recent call last): 
!! File "<stdin>", line 2, in <module> 
!! NameError: name 'asdf' is not defined 

Sin embargo, sin duda recomendaría el uso del módulo de registro de Python estándar, según lo sugerido por rlotun. No es lo más fácil de configurar, pero es muy personalizable.

+4

"no es lo más fácil de configurar" implica que es * difícil * de configurar, pero eso no es cierto, 'logging.basicConfig()' en la función principal es adecuado para la mayoría de las aplicaciones simples. – SingleNegationElimination

+1

Su código es útil cuando no puede usar el paquete de registro. P.ej. Al implementar un controlador de registro :-) – Doomsday

+2

@Doomsday, creo que la implementación de un ['logging.Handler'] (https://docs.python.org/library/logging.html#handler-objects) podría ser la única buena utilizar para este código. Para la pregunta original de OP, OP debería usar [logging] (http://docs.python.org/library/logging.html) con 'logging.exception' o log en un nivel inferior con' exc_info = True'. – KyleWpppd

91

Tome un vistazo a logging.exception (Python Logging Module)

import logging 
def foo(): 
    try: 
     some_code() 
    except: 
     logging.exception('') 

Esto debe tomar automáticamente el cuidado de conseguir el rastreo de la excepción actual e iniciar sesión correctamente.

+2

'except' catch-all puede ser una mala idea: http://stackoverflow.com/a/4990739/1091116 – d33tah

5

En primer lugar, considere utilizar un tipo de excepción adecuado en su cláusula except. Entonces, nombrando la excepción, puede imprimirlo:

try: 
    1/0 
except Exception as e: 
    print e 

Dependending de la versión de Python, debe utilizar

except Exception, e 
+2

La impresión no está registrando. Use 'logging.exception (exc)'. –

+1

@ChrisJohnson has recomendado 'logging.exception (exc)' en algunos comentarios en esta página, pero es una mala idea. El primer argumento para 'logging.exception' no es para la excepción de registro (Python simplemente toma el del actual bloque' except: 'por magia), es para el * mensaje * para iniciar sesión antes del rastreo.Especificar la excepción como el mensaje hace que se convierta en una cadena, lo que da como resultado la duplicación del mensaje de excepción. Si no tiene un mensaje significativo para iniciar sesión con su excepción, use 'logging.exception ('')', pero 'logging.exception (exc)' tiene poco sentido. –

40

Las excepciones de registro son tan simples como agregar el argumento exc_info = Palabra clave verdadera a cualquier mensaje de registro, ver la entrada para Logger.bug en http://docs.python.org/2/library/logging.html.

Ejemplo:

try: 
    raise Exception('lala') 
except Exception: 
    logging.info('blah', exc_info=True) 

salida (dependiendo, por supuesto, en su registro de configuración de controlador):

2012-11-29 10:18:12,778 - root - INFO - <ipython-input-27-5af852892344> : 3 - blah 
Traceback (most recent call last): 
    File "<ipython-input-27-5af852892344>", line 1, in <module> 
    try: raise Exception('lala') 
Exception: lala 
+2

Vas a hacer un gran esfuerzo. ¿Por qué no simplemente 'logging.exception (exc)'? –

+5

logging.exception es la abreviatura de logging.error (..., exc_info = True), por lo que si intenta registrar la excepción como un error, sería mejor usar logging.exception. Si desea registrar una excepción formateada en un nivel de registro que no sea un error, debe usar exc_info = True. – NeilenMarais

6

En Python 3.5 se puede pasar instancia de excepción en exc_info argumento:

import logging 
try: 
    1/0 
except Exception as e: 
    logging.error('Error at %s', 'division', exc_info=e) 
Cuestiones relacionadas