Ricerca…


Introduzione alla registrazione di Python

Questo modulo definisce funzioni e classi che implementano un sistema di registrazione eventi flessibile per applicazioni e librerie.

Il vantaggio principale di avere l'API di registrazione fornita da un modulo di libreria standard è che tutti i moduli Python possono partecipare alla registrazione, quindi il registro delle applicazioni può includere i propri messaggi integrati con i messaggi di moduli di terze parti.

Quindi iniziamo:

Esempio di configurazione direttamente nel codice

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')

Esempio di uscita:

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

Esempio di configurazione tramite un file INI

Supponendo che il file sia denominato logging_config.ini. Ulteriori dettagli sul formato del file si trovano nella sezione di configurazione della registrazione del tutorial di registrazione .

[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

Quindi usa logging.config.fileConfig() nel codice:

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')

Esempio di configurazione tramite un dizionario

A partire da Python 2.7, è possibile utilizzare un dizionario con i dettagli di configurazione. PEP 391 contiene un elenco degli elementi obbligatori e facoltativi nel dizionario di configurazione.

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')

Registrazione delle eccezioni

Se si desidera registrare eccezioni, è possibile e utilizzare il metodo 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

Non passare l'eccezione come argomento:

Poiché logging.exception(msg) aspetta un msg arg, è un errore comune passare l'eccezione alla chiamata di registrazione come questa:

>>> 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

Mentre potrebbe sembrare che questa sia la cosa giusta da fare in un primo momento, è in realtà problematico a causa del motivo per cui le eccezioni e le varie codifiche funzionano insieme nel modulo di registrazione:

>>> 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

Cercando di registrare un'eccezione che contiene caratteri Unicode, in questo modo fallirà miseramente . Nasconderà lo stacktrace dell'eccezione originale sovrascrivendolo con uno nuovo che viene generato durante la formattazione della tua chiamata logging.exception(e) .

Ovviamente, nel tuo codice, potresti essere a conoscenza della codifica delle eccezioni. Tuttavia, le librerie di terze parti potrebbero gestirle in un modo diverso.

Uso corretto:

Se invece dell'eccezione si passa un messaggio e si lascia che Python faccia la sua magia, funzionerà:

>>> 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

Come puoi vedere, in questo caso non usiamo e , la chiamata a logging.exception(...) formatta magicamente l'eccezione più recente.

Registrazione delle eccezioni con livelli di log non ERROR

Se si desidera registrare un'eccezione con un altro livello di registro diverso da ERRORE, è possibile utilizzare l'argomento exc_info dei logger predefiniti:

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

Accedere al messaggio dell'eccezione

Siate consapevoli che le librerie disponibili potrebbero generare eccezioni con i messaggi come qualsiasi codice unicode o stringhe di byte (utf-8 se siete fortunati). Se hai davvero bisogno di accedere al testo di un'eccezione, l'unico modo affidabile, che funzionerà sempre, è usare repr(e) o la formattazione della stringa %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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow