I'm running the following snippet in Python 2.7.12 under macOS Sierra but I get KeyErrors:
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()
The error I'm getting is this:
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
Any ideas?
Thanks in advance.
解决方案
A better solution would be to explicitly add the handlers you want (rather than using basicConfig()) and attach the filter to them. Then there's no need to patch PIL (or any other) loggers, nor to pass extra to logging calls. The filter method just needs to set
record.task = 'foo'
rather than messing with record.args.