Python Language
Skogsavverkning
Sök…
Introduktion till Python Logging
Den här modulen definierar funktioner och klasser som implementerar ett flexibelt händelseloggningssystem för applikationer och bibliotek.
Den viktigaste fördelen med att ha loggnings-API som tillhandahålls av en standardbiblioteksmodul är att alla Python-moduler kan delta i loggningen, så din applikationslogg kan inkludera dina egna meddelanden integrerade med meddelanden från tredjepartsmoduler.
Så låt oss börja:
Exempel på konfiguration direkt i kod
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')
Utgångsexempel:
2016-07-26 18:53:55,332 root DEBUG this is a debug test
Exempel på konfiguration via en INI-fil
Förutsatt att filen heter logging_config.ini. Mer information om filformatet är i loggningskonfiguration delen av loggnings handledning .
[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
logging.config.fileConfig()
i koden:
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')
Exempel på konfiguration via en ordlista
Från Python 2.7 kan du använda en ordlista med konfigurationsdetaljer. PEP 391 innehåller en lista över obligatoriska och valfria element i konfigurationsordlistan.
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')
Loggningsundantag
Om du vill logga undantag kan du och bör använda 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
Passera inte undantaget som argument:
Eftersom logging.exception(msg)
förväntar sig ett msg
arg, är det en vanlig fallgrop att överföra undantaget till loggningssamtalet så här:
>>> 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
Det kan se ut som om det här är rätt att göra i början, men det är faktiskt problematiskt på grund av att undantag och olika kodningar fungerar tillsammans i loggmodulen:
>>> 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
Om du försöker logga ett undantag som innehåller unicode-tecken, kommer detta sätt att misslyckas . Det kommer att dölja stacktracket för det ursprungliga undantaget genom att åsidosätta det med ett nytt som höjs under formateringen av ditt logging.exception(e)
-samtal.
Uppenbarligen i din egen kod kanske du känner till kodningen i undantag. Emellertid kan bibliotek från tredje part hantera detta på ett annat sätt.
Rätt användning:
Om du istället för undantaget bara skickar ett meddelande och låter python göra sin magi, fungerar det:
>>> 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
Som ni ser använder vi faktiskt inte e
i så fall, logging.exception(...)
samtalet till logging.exception(...)
magiskt det senaste undantaget.
Loggningsundantag med icke ERROR-loggnivåer
Om du vill logga ett undantag med en annan loggnivå än ERROR, kan du använda exc_info
argumentet för standardloggarna:
logging.debug('exception occurred', exc_info=1)
logging.info('exception occurred', exc_info=1)
logging.warning('exception occurred', exc_info=1)
Få åtkomst till undantagets meddelande
Var medveten om att bibliotek där ute kan kasta undantag med meddelanden som någon av unicode eller (utf-8 om du har tur) byte-strängar. Om du verkligen behöver komma åt ett undantags text, är det enda pålitliga sättet, som alltid fungerar, att använda repr(e)
eller %r
strängen formatering:
>>> 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