当我在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'
。所以我添加了一行
rfh.setLevel(logging.DEBUG)
在调用addHandler
之前,然后最后一行抛出AttributeError: RotatingFileHandler instance has no attribute 'filters'
。因此,如果我手动将过滤器设置为空列表,那么它会抱怨没有属性lock
等。
当我删除delay=True
以将其保留为False
as documented here的默认值时,问题就会完全消失。
我错过了什么吗?如何正确使用delay
类的RotatingFileHandler
参数?
编辑:经过进一步分析(在我自己的答案中提供),这看起来像一个错误,但我在Python bug tracker找不到关于此的错误报告,甚至尝试不同的搜索字词,所以我想我会报告它。
但是,如果有人能够找到实际的错误报告,那么我可以避免提交重复的报告并浪费Python开发人员的时间。我会暂时报告错误几个小时,如果有人发布了当前错误报告的答案,那么我会接受这个问题的答案。
答案 0 :(得分:5)
我已经调查了这个问题:它是在2009年1月20日的Python SVN r68829中修复的。这是在2.6.1发布之后但在2.6.2发布之前。
请升级到Python 2.6.2或更高版本。
我已更新the bug you filed。 BTW提交的原始错误报告是#5013,您可以通过搜索RotatingFileHandler
的所有问题(不仅仅是公开的问题)找到,例如this(来自this page)。
答案 1 :(得分: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
方法中,shouldRollover
和doRollover
方法在emit
之前调用记录。这会导致调用自己认为__init__
进程已完成的方法。
这看起来像一个错误,所以如果我发现它已被报道,我会报告它。