[Zconfig] SVN: ZConfig/trunk/ Added support for file rotation by time by specifying when and
Jim Fulton
jim at zope.com
Thu Sep 4 15:21:31 EDT 2008
Log message for revision 90823:
Added support for file rotation by time by specifying when and
interval, rather than max-size, for log files.
Changed:
U ZConfig/trunk/NEWS.txt
U ZConfig/trunk/ZConfig/components/logger/handlers.py
U ZConfig/trunk/ZConfig/components/logger/handlers.xml
U ZConfig/trunk/ZConfig/components/logger/loghandler.py
U ZConfig/trunk/ZConfig/components/logger/tests/test_logger.py
-=-
Modified: ZConfig/trunk/NEWS.txt
===================================================================
--- ZConfig/trunk/NEWS.txt 2008-09-04 19:15:42 UTC (rev 90822)
+++ ZConfig/trunk/NEWS.txt 2008-09-04 19:21:31 UTC (rev 90823)
@@ -2,9 +2,12 @@
Change History for ZConfig
==========================
-ZConfig 2.5.2 (unreleased)
+ZConfig 2.6.0 (2008/09/03)
--------------------------
+- Added support for file rotation by time by specifying when and
+ interval, rather than max-size, for log files.
+
- Removed dependency on setuptools from the setup.py.
Modified: ZConfig/trunk/ZConfig/components/logger/handlers.py
===================================================================
--- ZConfig/trunk/ZConfig/components/logger/handlers.py 2008-09-04 19:15:42 UTC (rev 90822)
+++ ZConfig/trunk/ZConfig/components/logger/handlers.py 2008-09-04 19:21:31 UTC (rev 90823)
@@ -97,6 +97,8 @@
path = self.section.path
max_bytes = self.section.max_size
old_files = self.section.old_files
+ when = self.section.when
+ interval = self.section.interval
if path == "STDERR":
if max_bytes or old_files:
raise ValueError("cannot rotate STDERR")
@@ -105,13 +107,23 @@
if max_bytes or old_files:
raise ValueError("cannot rotate STDOUT")
handler = loghandler.StreamHandler(sys.stdout)
- elif max_bytes or old_files:
- if not max_bytes:
- raise ValueError("max-bytes must be set for log rotation")
+ elif when or max_bytes or old_files or interval:
if not old_files:
raise ValueError("old-files must be set for log rotation")
- handler = loghandler.RotatingFileHandler(
- path, maxBytes=max_bytes, backupCount=old_files)
+ if when:
+ if max_bytes:
+ raise ValueError("can't set *both* max_bytes and when")
+ if not interval:
+ interval = 1
+ handler = loghandler.TimedRotatingFileHandler(
+ path, when=when, interval=interval,
+ backupCount=old_files)
+ elif max_bytes:
+ handler = loghandler.RotatingFileHandler(
+ path, maxBytes=max_bytes, backupCount=old_files)
+ else:
+ raise ValueError(
+ "max-bytes or when must be set for log rotation")
else:
handler = loghandler.FileHandler(path)
return handler
Modified: ZConfig/trunk/ZConfig/components/logger/handlers.xml
===================================================================
--- ZConfig/trunk/ZConfig/components/logger/handlers.xml 2008-09-04 19:15:42 UTC (rev 90822)
+++ ZConfig/trunk/ZConfig/components/logger/handlers.xml 2008-09-04 19:21:31 UTC (rev 90823)
@@ -32,6 +32,8 @@
<key name="path" required="yes"/>
<key name="old-files" required="no" default="0" datatype="integer"/>
<key name="max-size" required="no" default="0" datatype="byte-size"/>
+ <key name="when" required="no" default="" datatype="string"/>
+ <key name="interval" required="no" default="0" datatype="integer"/>
<key name="format"
default="------\n%(asctime)s %(levelname)s %(name)s %(message)s"
datatype=".log_format"/>
Modified: ZConfig/trunk/ZConfig/components/logger/loghandler.py
===================================================================
--- ZConfig/trunk/ZConfig/components/logger/loghandler.py 2008-09-04 19:15:42 UTC (rev 90822)
+++ ZConfig/trunk/ZConfig/components/logger/loghandler.py 2008-09-04 19:21:31 UTC (rev 90823)
@@ -19,6 +19,8 @@
from logging import Handler, StreamHandler
from logging.handlers import RotatingFileHandler as _RotatingFileHandler
+from logging.handlers import TimedRotatingFileHandler \
+ as _TimedRotatingFileHandler
from logging.handlers import SysLogHandler, BufferingHandler
from logging.handlers import HTTPHandler, SMTPHandler
from logging.handlers import NTEventLogHandler as Win32EventLogHandler
@@ -123,7 +125,21 @@
def reopen(self):
self.doRollover()
+class TimedRotatingFileHandler(_TimedRotatingFileHandler):
+ def __init__(self, *args, **kw):
+ _TimedRotatingFileHandler.__init__(self, *args, **kw)
+ self._wr = weakref.ref(self, _remove_from_reopenable)
+ _reopenable_handlers.append(self._wr)
+
+ def close(self):
+ _TimedRotatingFileHandler.close(self)
+ _remove_from_reopenable(self._wr)
+
+ def reopen(self):
+ self.doRollover()
+
+
class NullHandler(Handler):
"""Handler that does nothing."""
Modified: ZConfig/trunk/ZConfig/components/logger/tests/test_logger.py
===================================================================
--- ZConfig/trunk/ZConfig/components/logger/tests/test_logger.py 2008-09-04 19:15:42 UTC (rev 90822)
+++ ZConfig/trunk/ZConfig/components/logger/tests/test_logger.py 2008-09-04 19:21:31 UTC (rev 90823)
@@ -188,6 +188,58 @@
logger.removeHandler(logfile)
logfile.close()
+ def test_with_timed_rotating_logfile(self):
+ fn = self.mktemp()
+ logger = self.check_simple_logger("<eventlog>\n"
+ " <logfile>\n"
+ " path %s\n"
+ " level debug\n"
+ " when D\n"
+ " old-files 11\n"
+ " </logfile>\n"
+ "</eventlog>" % fn)
+ logfile = logger.handlers[0]
+ self.assertEqual(logfile.level, logging.DEBUG)
+ self.assertEqual(logfile.backupCount, 11)
+ self.assertEqual(logfile.interval, 86400)
+ self.assert_(isinstance(logfile, loghandler.TimedRotatingFileHandler))
+ logger.removeHandler(logfile)
+ logfile.close()
+
+ def test_with_timed_rotating_logfile(self):
+ fn = self.mktemp()
+ logger = self.check_simple_logger("<eventlog>\n"
+ " <logfile>\n"
+ " path %s\n"
+ " level debug\n"
+ " when D\n"
+ " interval 3\n"
+ " old-files 11\n"
+ " </logfile>\n"
+ "</eventlog>" % fn)
+ logfile = logger.handlers[0]
+ self.assertEqual(logfile.level, logging.DEBUG)
+ self.assertEqual(logfile.backupCount, 11)
+ self.assertEqual(logfile.interval, 86400*3)
+ self.assert_(isinstance(logfile, loghandler.TimedRotatingFileHandler))
+ logger.removeHandler(logfile)
+ logfile.close()
+
+ def test_with_timed_rotating_logfile_and_size_should_fail(self):
+ fn = self.mktemp()
+ self.assertRaises(
+ ValueError,
+ self.check_simple_logger, "<eventlog>\n"
+ " <logfile>\n"
+ " path %s\n"
+ " level debug\n"
+ " max-size 5mb\n"
+ " when D\n"
+ " old-files 10\n"
+ " </logfile>\n"
+ "</eventlog>" % fn)
+
+
def check_standard_stream(self, name):
old_stream = getattr(sys, name)
conf = self.get_config("""
@@ -444,6 +496,12 @@
max-size 1mb
old-files 3
</logfile>
+ <logfile>
+ path %(path1)s
+ level info
+ when D
+ old-files 3
+ </logfile>
</logger>
<logger>
More information about the ZConfig
mailing list