Created
January 17, 2012 08:19
-
-
Save cheeming/1625617 to your computer and use it in GitHub Desktop.
Backported WatchedFileHandler for python2.4 (copy-paste from python 2.6 standard library). Did some minor testing it should work as drop in replacement.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from stat import ST_DEV, ST_INO | |
import logging | |
import os | |
try: | |
import codecs | |
except ImportError: | |
codecs = None | |
class WatchedFileHandler(logging.FileHandler): | |
""" | |
A handler for logging to a file, which watches the file | |
to see if it has changed while in use. This can happen because of | |
usage of programs such as newsyslog and logrotate which perform | |
log file rotation. This handler, intended for use under Unix, | |
watches the file to see if it has changed since the last emit. | |
(A file has changed if its device or inode have changed.) | |
If it has changed, the old file stream is closed, and the file | |
opened to get a new stream. | |
This handler is not appropriate for use under Windows, because | |
under Windows open files cannot be moved or renamed - logging | |
opens the files with exclusive locks - and so there is no need | |
for such a handler. Furthermore, ST_INO is not supported under | |
Windows; stat always returns zero for this value. | |
This handler is based on a suggestion and patch by Chad J. | |
Schroeder. | |
""" | |
def __init__(self, filename, mode='a', encoding=None, delay=0): | |
# NOTE: seems python before v2.6 doesn't set self.encoding | |
if codecs is None: | |
encoding = None | |
self.encoding = encoding | |
logging.FileHandler.__init__(self, filename, mode, encoding) | |
if not os.path.exists(self.baseFilename): | |
self.dev, self.ino = -1, -1 | |
else: | |
stat = os.stat(self.baseFilename) | |
self.dev, self.ino = stat[ST_DEV], stat[ST_INO] | |
def emit(self, record): | |
""" | |
Emit a record. | |
First check if the underlying file has changed, and if it | |
has, close the old stream and reopen the file to get the | |
current stream. | |
""" | |
if not os.path.exists(self.baseFilename): | |
stat = None | |
changed = 1 | |
else: | |
stat = os.stat(self.baseFilename) | |
changed = (stat[ST_DEV] != self.dev) or (stat[ST_INO] != self.ino) | |
if changed and self.stream is not None: | |
self.stream.flush() | |
self.stream.close() | |
self.stream = self._open() | |
if stat is None: | |
stat = os.stat(self.baseFilename) | |
self.dev, self.ino = stat[ST_DEV], stat[ST_INO] | |
logging.FileHandler.emit(self, record) | |
# NOTE: copy this from python v2.6 std lib | |
# seems python before v2.6 doesn't have this | |
def _open(self): | |
""" | |
Open the current base file with the (original) mode and encoding. | |
Return the resulting stream. | |
""" | |
if self.encoding is None: | |
stream = open(self.baseFilename, self.mode) | |
else: | |
stream = codecs.open(self.baseFilename, self.mode, self.encoding) | |
return stream |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment