Buscar..


Introducción al registro de Python

Este módulo define funciones y clases que implementan un sistema flexible de registro de eventos para aplicaciones y bibliotecas.

El beneficio clave de tener la API de registro proporcionada por un módulo de biblioteca estándar es que todos los módulos de Python pueden participar en el registro, por lo que el registro de su aplicación puede incluir sus propios mensajes integrados con mensajes de módulos de terceros.

Entonces, comencemos:

Ejemplo de configuración directamente en el código

import logging

logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
        '%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

logger.debug('this is a %s test', 'debug')

Ejemplo de salida:

2016-07-26 18:53:55,332 root         DEBUG    this is a debug test

Ejemplo de configuración a través de un archivo INI

Suponiendo que el archivo se llama logging_config.ini. Más detalles sobre el formato de archivo se encuentran en la sección de configuración de registro del tutorial de registro .

[loggers]
keys=root

[handlers]
keys=stream_handler

[formatters]
keys=formatter

[logger_root]
level=DEBUG
handlers=stream_handler

[handler_stream_handler]
class=StreamHandler
level=DEBUG
formatter=formatter
args=(sys.stderr,)

[formatter_formatter]
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s

Luego use logging.config.fileConfig() en el código:

import logging
from logging.config import fileConfig

fileConfig('logging_config.ini')
logger = logging.getLogger()
logger.debug('often makes a very good meal of %s', 'visiting tourists')

Ejemplo de configuración a través de un diccionario

A partir de Python 2.7, puede usar un diccionario con detalles de configuración. PEP 391 contiene una lista de los elementos obligatorios y opcionales en el diccionario de configuración.

import logging
from logging.config import dictConfig

logging_config = dict(
    version = 1,
    formatters = {
        'f': {'format':
              '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'}
        },
    handlers = {
        'h': {'class': 'logging.StreamHandler',
              'formatter': 'f',
              'level': logging.DEBUG}
        },
    root = {
        'handlers': ['h'],
        'level': logging.DEBUG,
        },
)

dictConfig(logging_config)

logger = logging.getLogger()
logger.debug('often makes a very good meal of %s', 'visiting tourists')

Excepciones de registro

Si desea registrar excepciones, puede y debe hacer uso del método logging.exception(msg) :

>>> import logging
>>> logging.basicConfig()
>>> try:
...     raise Exception('foo')
... except:
...     logging.exception('bar')
...
ERROR:root:bar
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: foo

No pase la excepción como argumento:

Como logging.exception(msg) espera un msg arg, es un error común para aprobar la excepción en el registro de llamadas de esta manera:

>>> try:
...     raise Exception('foo')
... except Exception as e:
...     logging.exception(e)
...
ERROR:root:foo
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: foo

Si bien puede parecer que esto es lo correcto al principio, en realidad es problemático debido a la forma en que las excepciones y las distintas codificaciones funcionan juntas en el módulo de registro:

>>> try:
...     raise Exception(u'föö')
... except Exception as e:
...     logging.exception(e)
...
Traceback (most recent call last):
  File "/.../python2.7/logging/__init__.py", line 861, in emit
    msg = self.format(record)
  File "/.../python2.7/logging/__init__.py", line 734, in format
    return fmt.format(record)
  File "/.../python2.7/logging/__init__.py", line 469, in format
    s = self._fmt % record.__dict__
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-2: ordinal not in range(128)
Logged from file <stdin>, line 4

Intentar registrar una excepción que contenga caracteres Unicode, de esta manera fallará miserablemente . Ocultará el seguimiento de pila de la excepción original al anularla con una nueva que se logging.exception(e) durante el formateo de su logging.exception(e) .

Obviamente, en su propio código, podría estar al tanto de la codificación en las excepciones. Sin embargo, las bibliotecas de terceros pueden manejar esto de una manera diferente.

Uso Correcto:

Si en lugar de la excepción simplemente pasa un mensaje y deja que Python haga su magia, funcionará:

>>> try:
...     raise Exception(u'föö')
... except Exception as e:
...     logging.exception('bar')
...
ERROR:root:bar
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: f\xf6\xf6

Como puede ver, en realidad no usamos e en ese caso, la llamada a logging.exception(...) formatea mágicamente la excepción más reciente.

Registro de excepciones con niveles de registro que no sean ERROR

Si desea registrar una excepción con un nivel de registro diferente al ERROR, puede usar el argumento exc_info de los registradores predeterminados:

logging.debug('exception occurred', exc_info=1)
logging.info('exception occurred', exc_info=1)
logging.warning('exception occurred', exc_info=1)

Accediendo al mensaje de la excepción.

Tenga en cuenta que las bibliotecas podrían generar excepciones con los mensajes como Unicode o (utf-8 si tiene suerte) de cadenas de bytes. Si realmente necesita acceder a un texto de excepción, la única forma confiable, que siempre funcionará, es usar repr(e) o el formato de cadena %r :

>>> try:
...     raise Exception(u'föö')
... except Exception as e:
...     logging.exception('received this exception: %r' % e)
...
ERROR:root:received this exception: Exception(u'f\xf6\xf6',)
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: f\xf6\xf6


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow