2016-09-13 2 views
0

Я смотрел на примерах, относящихся к контексту здесь: Logging CookbookНе удается получить этот обычай пример каротаж адаптер для работы

Однако, я не могу получить следующий пример работы. Пример должен демонстрировать использование пользовательских адаптеров и продолжается в следующем виде:

# Here is a simple example: 

class CustomAdapter(logging.LoggerAdapter): 
""" 
This example adapter expects the passed in dict-like object to have a 
'connid' key, whose value in brackets is prepended to the log message. 
""" 
def process(self, msg, kwargs): 
    return '[%s] %s' % (self.extra['connid'], msg), kwargs 

# which you can use like this: 

logger = logging.getLogger(__name__) 
adapter = CustomAdapter(logger, {'connid': some_conn_id}) 

# Then any events that you log to the adapter will have the value of some_conn_id prepended to the log messages. 

Однако, независимо от того, что я пытался, я всегда получаю ключевую ошибку:

logger = logging.getLogger(__name__) 

syslog = logging.StreamHandler() 
formatter = logging.Formatter('%(asctime)s <<<CONTEXT: %(my_context)s>>> : %(message)s') 
syslog.setFormatter(formatter) 

adapter = CustomAdapter(logger, {'my_context': '1956'}) 

logger.setLevel(logging.INFO) 
logger.addHandler(syslog) 

logger.info('The sky is so blue', {'my_context': '6642'}) 


Traceback (most recent call last): 
File "/Users/me/apps/Darwin64/python2.7/lib/python2.7/logging/__init__.py", line 859, in emit 
msg = self.format(record) 
File "/Users/me/apps/Darwin64/python2.7/lib/python2.7/logging/__init__.py", line 732, in format 
return fmt.format(record) 
File "/Users/me/apps/Darwin64/python2.7/lib/python2.7/logging/__init__.py", line 474, in format 
s = self._fmt % record.__dict__ 
KeyError: 'my_context' 
Logged from file myApp.py, line 62 

Что это что я поступаю неправильно?

--- Решение: EDIT_01 ---

Я изменил код таким образом, что он использует adapter.info('The sky is so blue', {'my_context': '6642'}). И это сработало. Однако мне пришлось удалить my_context из форматирования. Однако с приведенным ниже кодом бит my_context жестко запрограммирован и независимо от того, через что я проходил через регистратор, он всегда будет отображать начальное значение. Есть ли способ передать некоторые значения адаптеру?

logger = logging.getLogger(__name__) 
syslog = logging.StreamHandler() 
formatter = logging.Formatter('%(asctime)s %(message)s') 
syslog.setFormatter(formatter) 
logger.addHandler(syslog) 
adapter = CustomAdapter(logger, {'my_context': '1956'}) 
logger.setLevel(logging.INFO) 
adapter.info('The sky is so blue', {'my_context': '6642'}) 

Это всегда генерировать:

2016-09-13 11:33:18,404 [1956] The sky is so blue 

даже мы проходим 6642 через регистратор.

ответ

2

Вы должны использовать адаптер для регистрации, а не для регистратора. Попробуйте это:

import logging 

class CustomAdapter(logging.LoggerAdapter): 
    def process(self, msg, kwargs): 
     # use my_context from kwargs or the default given on instantiation 
     my_context = kwargs.pop('my_context', self.extra['my_context']) 
     return '[%s] %s' % (my_context, msg), kwargs 

logger = logging.getLogger(__name__) 
syslog = logging.StreamHandler() 
formatter = logging.Formatter('%(asctime)s %(message)s') 
syslog.setFormatter(formatter) 
logger.addHandler(syslog) 
adapter = CustomAdapter(logger, {'my_context': '1956'}) 
logger.setLevel(logging.INFO) 

adapter.info('The sky is so blue', my_context='6642') 
adapter.info('The sky is so blue') 

Выход:

2016-09-13 14:49:28,539 [6642] The sky is so blue 
2016-09-13 14:49:28,540 [1956] The sky is so blue 
+0

Спасибо, вы правы. Я до сих пор не в состоянии полностью понять концепцию адаптеров. Тем не менее, все еще существует проблема: значение 'my_context' теперь жестко закодировано. См. «EDIT_01». – symbolix

+0

Две вещи: вы должны передать 'my_context' как аргумент ключевого слова вместо того, чтобы передавать его в dict. Посмотрите на источник модуля регистрации. Вы не отправили свою реальную реализацию CustomAdapter –

+0

Спасибо. Это хорошее решение моего вопроса. Все эти понятия «Адаптеры» и «Фильтры» настолько абстрактны, я продолжаю читать документы, и я постоянно с ними разбираюсь. Ваш «CustomAdapter» отличается тем, что я не видел ни в одном учебнике, еще раз спасибо. Можно ли предположить, что «Адаптеры» имеют дело с ** информацией ** стороной ведения журнала (сообщения, контекст и т. Д.)? Это открывает возможность для передачи всей информации, даже сложных данных, таких как трассировка стека, вместе с сообщениями журнала? – symbolix

Смежные вопросы