如何在Python模块中正确添加自定义日志过滤器
我正在macOS Sierra下运行Python 2.7.12中的以下代码段,但我得到了如何在Python模块中正确添加自定义日志过滤器,python,python-2.7,logging,Python,Python 2.7,Logging,我正在macOS Sierra下运行Python 2.7.12中的以下代码段,但我得到了KeyErrors: import logging from PIL import Image class TaskAddingFilter(logging.Filter): def __init__(self): logging.Filter.__init__(self) def filter(self, record): record.args = r
KeyError
s:
import logging
from PIL import Image
class TaskAddingFilter(logging.Filter):
def __init__(self):
logging.Filter.__init__(self)
def filter(self, record):
record.args = record.args + ('task', '')
logging.basicConfig(
filename='mylog.txt',
format='%(asctime)-19.19s|%(task)-36s|%(levelname)s:%(name)s:%(lineno)s: %(message)s',
level=eval('logging.%s' % 'DEBUG'))
# My attempt to "monkey-patch" PIL's logger
for name, logger in logging.Logger.manager.loggerDict.iteritems():
logger = logging.getLogger(name)
if name.startswith('PIL'):
logger.addFilter(TaskAddingFilter())
logger = logging.getLogger('demo')
def tryThis():
with open('my_image.png', 'rb') as im:
logger.debug('Attempting to read image size...', extra={'task': '123'})
try:
image = Image.open(im)
w, h = image.size
image.save('my_image_out.png', 'PNG')
except IOError:
logger.error('Processing failed!', extra={'task': '123'})
raise Exception()
tryThis()
我得到的错误是:
Traceback (most recent call last):
File "/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 861, in emit
msg = self.format(record)
File "/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 734, in format
return fmt.format(record)
File "/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 469, in format
s = self._fmt % record.__dict__
KeyError: 'task'
Logged from file PngImagePlugin.py, line 135
有什么想法吗
提前感谢。因此,对于其他感兴趣的人,我最终打开了一个,多亏了contributor@wiredfool,我想出了以下解决方案:
import logging
from PIL import Image
class TaskAddingFilter(logging.Filter):
def __init__(self):
logging.Filter.__init__(self)
def filter(self, record):
record.args = record.args + ('task', '123')
logger = logging.getLogger('THEDEMO')
Image.init()
logging.basicConfig(
filename='mylog.txt',
format='%(asctime)-19.19s|%(task)-36s|%(levelname)s:%(name)s:%(lineno)s: %(message)s',
level=eval('logging.%s' % 'DEBUG'))
for name, elogger in logging.Logger.manager.loggerDict.iteritems():
elogger = logging.getLogger(name)
if name.startswith('PIL'):
elogger.addFilter(TaskAddingFilter())
def tryThis():
with open('my_image.png', 'rb') as im:
logger.debug('Attempting to read image size...', extra={'task': '123'})
try:
image = Image.open(im)
w, h = image.size
image.save('my_image_out.png', 'PNG')
print 'all ran well'
except IOError:
logger.error('Processing failed!', extra={'task': 123})
raise Exception()
tryThis()
因此,对于其他感兴趣的人,我最终打开了一个,多亏了contributor@wiredfool,我想出了以下解决方案:
import logging
from PIL import Image
class TaskAddingFilter(logging.Filter):
def __init__(self):
logging.Filter.__init__(self)
def filter(self, record):
record.args = record.args + ('task', '123')
logger = logging.getLogger('THEDEMO')
Image.init()
logging.basicConfig(
filename='mylog.txt',
format='%(asctime)-19.19s|%(task)-36s|%(levelname)s:%(name)s:%(lineno)s: %(message)s',
level=eval('logging.%s' % 'DEBUG'))
for name, elogger in logging.Logger.manager.loggerDict.iteritems():
elogger = logging.getLogger(name)
if name.startswith('PIL'):
elogger.addFilter(TaskAddingFilter())
def tryThis():
with open('my_image.png', 'rb') as im:
logger.debug('Attempting to read image size...', extra={'task': '123'})
try:
image = Image.open(im)
w, h = image.size
image.save('my_image_out.png', 'PNG')
print 'all ran well'
except IOError:
logger.error('Processing failed!', extra={'task': 123})
raise Exception()
tryThis()
更好的解决方案是显式添加所需的处理程序(而不是使用
basicConfig()
)并将筛选器附加到它们。这样就不需要给PIL(或任何其他)记录器打补丁,也不需要向日志调用传递额外的。过滤器方法只需要设置
record.task = 'foo'
更好的解决方案是显式地添加所需的处理程序(而不是使用basicConfig()
)并将筛选器附加到它们,而不是处理record.args。这样就不需要给PIL(或任何其他)记录器打补丁,也不需要向日志调用传递额外的。过滤器方法只需要设置
record.task = 'foo'
我没有去处理record.args
而是尝试了你的代码片段,它在这里工作得很好。非常感谢您让我了解了有关日志记录
模块的更多信息。您的代码片段中的哪一行对应于PngImagePlugin.py,第135行
?@CSJ是这一行:image=image.open(im)
。这一行开始使用库及其记录器。你的意思是在这一行之前它已经为PIL
进行了猴子补丁,对吗?没错!我试过你的代码片段,在这里效果很好。非常感谢您让我了解了有关日志记录
模块的更多信息。您的代码片段中的哪一行对应于PngImagePlugin.py,第135行
?@CSJ是这一行:image=image.open(im)
。这一行开始使用库及其记录器。你的意思是在这一行之前它已经为PIL
进行了猴子补丁,对吗?没错!但是args
来自哪里?但是args
来自哪里?