summaryrefslogtreecommitdiff
path: root/Lib/logging
diff options
context:
space:
mode:
authorVinay Sajip <vinay_sajip@yahoo.co.uk>2007-01-14 21:49:59 +0000
committerVinay Sajip <vinay_sajip@yahoo.co.uk>2007-01-14 21:49:59 +0000
commitd9fea3ca2643bb723842a0defca744a13ad311ee (patch)
tree93e0765a00471aaf20f9ce646802f0446e1a3a23 /Lib/logging
parent2e1518da293f677ee7d27ac7679e7016e81da141 (diff)
downloadcpython-d9fea3ca2643bb723842a0defca744a13ad311ee.tar.gz
Added WatchedFileHandler (based on SF patch #1598415)
Diffstat (limited to 'Lib/logging')
-rw-r--r--Lib/logging/handlers.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index cd8d5d2f74..1a82d9e743 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