views:

80

answers:

2

When I run the following code under Python 2.6

import logging
from logging.handlers import RotatingFileHandler

rfh = RotatingFileHandler("testing.log", delay=True)
logging.getLogger().addHandler(rfh)
logging.warning("Boo!")

then the last line throws AttributeError: RotatingFileHandler instance has no attribute 'level'. So I add the line

rfh.setLevel(logging.DEBUG)

before the call to addHandler, and then the last line throws AttributeError: RotatingFileHandler instance has no attribute 'filters'. So if I manually set filters to be an empty list, then it complains about not having the attribute lock, etc.

When I remove the delay=True to leave it as the default value of False as documented here, the problem completely goes away.

Am I missing something? How do I properly use the delay parameter of the RotatingFileHandler class?

EDIT: Upon further analysis (presented in my own answer below), this looks like a bug, but I can't find a bug report on this in the Python bug tracker, even trying different search terms, so I guess I'll report it.

However, if someone can locate the actual bug report, then I can avoid submitting a duplicate reporting and wasting the time of the Python developers. I'll hold off on reporting the bug for a few hours, and if someone posts an answer that has the current bug report, then I'll accept that answer for this question.

A: 

I think I've just figured this out:

So it looks like one of the parent __init__ methods somewhere up the class hierarchy isn't getting called when delay is set. Indeed, examining the source code to the file logging/__init__.py in my Python install, I see the following code in the FileHandler.__init__ method:

if delay:
    self.stream = None
else:
    stream = self._open()
    StreamHandler.__init__(self, stream)

It looks like the FileHandler.emit method checks for un-opened streams and finishes initialization when logging is performed:

if self.stream is None:
    stream = self._open()
    StreamHandler.__init__(self, stream)
StreamHandler.emit(self, record)

So the problem is that in the BaseRotatingHandler.emit method, the shouldRollover and doRollover methods are called before emit-ing the record. This causes methods to be called which themselves assumed that the __init__ process has completed.

This looks like a bug, so I'll report it as such if I can't find it having been already been reported.

Eli Courtwright
+1  A: 

I've investigated this issue: it was fixed in Python SVN r68829 dated 20 Jan, 2009. This was after the release of 2.6.1 but before the release of 2.6.2.

Please upgrade to Python 2.6.2, or a later version.

I've updated the bug you filed. BTW the original bug report filed was #5013, which you could have found by searching all issues (not just open ones) for RotatingFileHandler, like this (from this page).

Vinay Sajip
Thanks! As for the original bug report, neither of the two problems it lists (formatters are reset and delay gets ignored on a rollover) seem to describe my issue. I actually did read that bug report before filing my own after searching all issues as you describe, and although it appears that bug's fix also solved my problem, nothing in the bug description led me to believe that this problem was related. Sorry for the hassle, and thanks again for the help.
Eli Courtwright