2013-07-09 15 views
46

Mój obecny format string jest:Jak dodać niestandardowe pole do łańcucha formatu dziennika Python?

formatter = logging.Formatter('%(asctime)s : %(message)s') 

i chcę dodać nowe pole o nazwie APP_NAME i który będzie miał inną wartość w każdym skrypcie zawierający tę formatowania.

import logging 
formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s') 
syslog.setFormatter(formatter) 
logger.addHandler(syslog) 

Ale nie jestem pewien, w jaki sposób przekazać tę wartość app_name do rejestratora interpolować w ciągu formatu. Mogę oczywiście sprawić, by pojawił się w wiadomości dziennika, ale przekazywał ją za każdym razem, ale jest to niechlujne.

Próbowałem:

logging.info('Log message', app_name='myapp') 
logging.info('Log message', {'app_name', 'myapp'}) 
logging.info('Log message', 'myapp') 

ale żadna praca.

+0

Czy na pewno chcesz przekazać to do każdego wywołania "log"? Jeśli tak, to spójrz na [the docs] (http://docs.python.org/3.3/library/logging.html#logrecord-objects), gdzie jest napisane: "Ta funkcja może być wykorzystana do wstrzyknięcia twoich własnych wartości do LogRecord ... "Ale wydaje się, że jest to główny powód użycia' logger = logging.getLogger ('myapp') 'i wypalenie go w wywołaniu' logger.info'. – abarnert

Odpowiedz

65

można użyć LoggingAdapter więc nie trzeba przekazać dodatkowe informacje z każdej rozmowy rejestrowania:

import logging 
extra = {'app_name':'Super App'} 

logger = logging.getLogger(__name__) 
syslog = logging.StreamHandler() 
formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s') 
syslog.setFormatter(formatter) 
logger.setLevel(logging.INFO) 
logger.addHandler(syslog) 

logger = logging.LoggerAdapter(logger, extra) 
logger.info('The sky is so blue') 

cylindryczne (coś)

2013-07-09 17:39:33,596 Super App : The sky is so blue 

Filters może również służyć do dodawania informacji kontekstowych.

import logging 

class AppFilter(logging.Filter): 
    def filter(self, record): 
     record.app_name = 'Super App' 
     return True 

logger = logging.getLogger(__name__) 
logger.addFilter(AppFilter()) 
syslog = logging.StreamHandler() 
formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s') 
syslog.setFormatter(formatter) 
logger.setLevel(logging.INFO) 
logger.addHandler(syslog) 

logger.info('The sky is so blue') 

produkuje podobny rekord dziennika.

+1

Jak możemy to określić w pliku 'config.ini'? Chciałbym dodać bieżącą nazwę hosta 'socket.gethostname()'. –

16

Musisz przekazać dyktat jako parametr dodatkowy, aby zrobić to w ten sposób.

logging.info('Log message', extra={'app_name': 'myapp'}) 

Dowód:

>>> import logging 
>>> logging.basicConfig(format="%(foo)s - %(message)s") 
>>> logging.warning('test', extra={'foo': 'bar'}) 
bar - test 

Ponadto, jako notatkę, jeśli starają się zalogować wiadomość bez minięciu dict, to nie zadziała.

>>> logging.warning('test') 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/logging/__init__.py", line 846, in emit 
    msg = self.format(record) 
    File "/usr/lib/python2.7/logging/__init__.py", line 723, in format 
    return fmt.format(record) 
    File "/usr/lib/python2.7/logging/__init__.py", line 467, in format 
    s = self._fmt % record.__dict__ 
KeyError: 'foo' 
Logged from file <stdin>, line 1 
+1

zapisał mój dzień :) – Anish

+0

Czy to też zadziała dla 'logging.info()'? Nie udało się, gdy próbowałem ostatni. :/ –

+0

Podoba mi się odpowiedź @ mr2ert. Możesz podać wartość domyślną dla dodatkowego pola, rozszerzając klasę 'logging.Formatter': class CustomFormatter (logging.Formatter): def format (self, record): if not hastrtr (record, 'foo') : record.foo = 'default_foo' powrotu super (CustomFormatter, self.format (rejestr) H = loggin.StreamHandler() h.setFormatter (CustomFormatter ('% (bla) s% (wiadomości) s') rejestrator = logging.getLogger ('bar') logger.addHandler (H) logger.error (z możliwością = { 'foo': 'foo} Ej!') logger.error ("Ej! ') – loutre

Powiązane problemy