当设置延迟参数时,RotatingFileHandler抛出异常

3 投票
2 回答
2625 浏览
提问于 2025-04-15 20:32

当我在 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 个回答

0

我想我刚刚搞明白了这个问题:

看起来在类的层级结构中,有一个父类的__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方法中,shouldRolloverdoRollover方法是在记录被emit之前就被调用了。这导致了一些方法被调用时,它们自己认为__init__过程已经完成。

这看起来像是一个bug,如果我找不到已经有人报告过的话,我会把它报告上去。

5

我调查了这个问题:它在2009年1月20日的Python SVN r68829中被修复。这是在2.6.1版本发布之后,但在2.6.2版本发布之前。

请升级到Python 2.6.2或更高版本。

我更新了你提交的这个bug。顺便提一下,最初的bug报告是#5013,你可以通过搜索所有问题(不仅仅是开放的问题)来找到它,搜索关键词RotatingFileHandler,就像这个链接(来自这个页面)。

撰写回答