diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2007-01-14 21:49:59 (GMT) |
---|---|---|
committer | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2007-01-14 21:49:59 (GMT) |
commit | 73306b07edda7e922d8f90f14dd97ec390467f1b (patch) | |
tree | a5b7ecef9ecc4d5f931ccf3940416b5ba90862a3 | |
parent | bb2cc698c1dd69ad57450bb48d64f2b8aaae7bb7 (diff) | |
download | cpython-73306b07edda7e922d8f90f14dd97ec390467f1b.zip cpython-73306b07edda7e922d8f90f14dd97ec390467f1b.tar.gz cpython-73306b07edda7e922d8f90f14dd97ec390467f1b.tar.bz2 |
Added WatchedFileHandler (based on SF patch #1598415)
-rw-r--r-- | Lib/logging/handlers.py | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index cd8d5d2..1a82d9e 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -28,6 +28,7 @@ To use, simply 'import logging' and log away! """ import sys, logging, socket, types, os, string, cPickle, struct, time, glob +from stat import ST_DEV, ST_INO try: import codecs @@ -282,6 +283,54 @@ class TimedRotatingFileHandler(BaseRotatingHandler): self.stream = open(self.baseFilename, 'w') self.rolloverAt = self.rolloverAt + self.interval +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): + logging.FileHandler.__init__(self, filename, mode, encoding) + 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: + 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) + class SocketHandler(logging.Handler): """ A handler class which writes logging records, in pickle format, to |