summaryrefslogtreecommitdiffstats
path: root/Lib/logging
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/logging')
-rw-r--r--Lib/logging/__init__.py27
-rw-r--r--Lib/logging/handlers.py49
2 files changed, 67 insertions, 9 deletions
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index 615dcc7..1415226 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -41,8 +41,8 @@ except ImportError:
__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
__status__ = "production"
-__version__ = "0.5.0.0"
-__date__ = "08 January 2007"
+__version__ = "0.5.0.1"
+__date__ = "09 January 2007"
#---------------------------------------------------------------------------
# Miscellaneous module data
@@ -764,17 +764,15 @@ class FileHandler(StreamHandler):
"""
Open the specified file and use it as the stream for logging.
"""
- if codecs is None:
- encoding = None
- if encoding is None:
- stream = open(filename, mode)
- else:
- stream = codecs.open(filename, mode, encoding)
- StreamHandler.__init__(self, stream)
#keep the absolute path, otherwise derived classes which use this
#may come a cropper when the current directory changes
+ if codecs is None:
+ encoding = None
self.baseFilename = os.path.abspath(filename)
self.mode = mode
+ self.encoding = encoding
+ stream = self._open()
+ StreamHandler.__init__(self, stream)
def close(self):
"""
@@ -784,6 +782,17 @@ class FileHandler(StreamHandler):
self.stream.close()
StreamHandler.close(self)
+ 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
+
#---------------------------------------------------------------------------
# Manager classes and functions
#---------------------------------------------------------------------------
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index 82896ad..41cbca1 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -32,6 +32,7 @@ try:
import cPickle as pickle
except ImportError:
import pickle
+from stat import ST_DEV, ST_INO
try:
import codecs
@@ -286,6 +287,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