当设置延迟参数时,RotatingFileHandler抛出异常
当我在 Python 2.6 下运行以下代码时
import logging
from logging.handlers import RotatingFileHandler
rfh = RotatingFileHandler("testing.log", delay=True)
logging.getLogger().addHandler(rfh)
logging.warning("Boo!")
最后一行出现了错误,提示 AttributeError: RotatingFileHandler instance has no attribute 'level'
。于是我在调用 addHandler
之前加了一行
rfh.setLevel(logging.DEBUG)
结果最后一行又出现了错误,提示 AttributeError: RotatingFileHandler instance has no attribute 'filters'
。所以如果我手动把 filters 设置为空列表,它又会抱怨没有 lock
这个属性,等等。
当我把 delay=True
去掉,改成默认值 False
,就像文档里说的那样,问题就完全消失了。
我是不是漏掉了什么?我该怎么正确使用 RotatingFileHandler
类的 delay
参数呢?
编辑:经过进一步分析(在我下面自己的回答中呈现),这看起来像是一个bug,但我在Python bug跟踪器上找不到这个bug的报告,尝试了不同的搜索词,所以我想我会提交一个报告。
不过,如果有人能找到实际的bug报告,那我就可以避免提交重复的报告,浪费Python开发者的时间。我会等几个小时再提交bug,如果有人回复了当前的bug报告,那我会接受那个答案来解决这个问题。
2 个回答
我想我刚刚搞明白了这个问题:
看起来在类的层级结构中,有一个父类的__init__
方法在设置了延迟的时候没有被调用。实际上,我查看了我Python安装中的logging/__init__.py
文件的源代码,发现FileHandler.__init__
方法里有以下代码:
if delay:
self.stream = None
else:
stream = self._open()
StreamHandler.__init__(self, stream)
看起来FileHandler.emit
方法会检查是否有未打开的流,并在进行日志记录时完成初始化:
if self.stream is None:
stream = self._open()
StreamHandler.__init__(self, stream)
StreamHandler.emit(self, record)
所以问题在于,在BaseRotatingHandler.emit
方法中,shouldRollover
和doRollover
方法是在记录被emit
之前就被调用了。这导致了一些方法被调用时,它们自己认为__init__
过程已经完成。
这看起来像是一个bug,如果我找不到已经有人报告过的话,我会把它报告上去。