2016-11-28 20 views
-1

我在MacOS塞拉利昂運行下面的代碼片段在Python 2.7.12 Python模塊添加自定義日誌過濾器,但我得到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 

任何想法?

在此先感謝。

+1

我試過你的代碼片段,它在這裏工作正常。就像感謝你讓我更多地學習了'logging'模塊。 – CSJ

+0

你的代碼段中的哪一行對應'PngImagePlugin.py,第135行? – CSJ

+0

@CSJ就是這樣一行:'image = Image.open(im)'。該行開始使用該庫以及其記錄器。 – kstratis

回答

0

所以對任何人有興趣,我最終打開一個issue on Pillow's repository並感謝貢獻者@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() 
1

一個更好的解決辦法是明確地添加你想要的處理器(而不是使用basicConfig())並將過濾器附加到它們上。然後,不需要修補PIL(或任何其他)記錄器,也不需要通過extra來記錄調用。該過濾器的方法只需要設置

record.task = 'foo' 

,而不是搞亂record.args