我一直在这里查看与上下文日志记录相关的示例: 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.
Run Code Online (Sandbox Code Playgroud)
但是,无论我尝试了什么,总是会遇到一个关键错误:
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
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
---解决方案: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'})
Run Code Online (Sandbox Code Playgroud)
这将始终生成:
2016-09-13 11:33:18,404 [1956] The sky is so blue
Run Code Online (Sandbox Code Playgroud)
即使我们正在6642通过记录器。
您必须使用适配器记录日志,而不是记录器。尝试这个:
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')
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)