[Zconfig] SVN: ZConfig/trunk/ZConfig/components/logger/ Added a
configuration option for specifying a subclass of
Shane Hathaway
shane at zope.com
Wed Jan 18 20:43:25 EST 2006
Log message for revision 41358:
Added a configuration option for specifying a subclass of
logging.Formatter. This is in support of the following proposal:
http://www.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/EnhanceTracebacksInPersistentLogs
Changed:
U ZConfig/trunk/ZConfig/components/logger/handlers.py
U ZConfig/trunk/ZConfig/components/logger/handlers.xml
U ZConfig/trunk/ZConfig/components/logger/tests/test_logger.py
-=-
Modified: ZConfig/trunk/ZConfig/components/logger/handlers.py
===================================================================
--- ZConfig/trunk/ZConfig/components/logger/handlers.py 2006-01-18 21:08:52 UTC (rev 41357)
+++ ZConfig/trunk/ZConfig/components/logger/handlers.py 2006-01-19 01:43:24 UTC (rev 41358)
@@ -54,6 +54,19 @@
value = value.replace(pattern, replacement)
return value
+def resolve(name):
+ """Given a dotted name, returns an object imported from a Python module."""
+ name = name.split('.')
+ used = name.pop(0)
+ found = __import__(used)
+ for n in name:
+ used += '.' + n
+ try:
+ found = getattr(found, n)
+ except AttributeError:
+ __import__(used)
+ found = getattr(found, n)
+ return found
class HandlerFactory(Factory):
def __init__(self, section):
@@ -67,8 +80,11 @@
def create(self):
import logging
logger = self.create_loghandler()
- logger.setFormatter(logging.Formatter(self.section.format,
- self.section.dateformat))
+ if self.section.formatter:
+ f = resolve(self.section.formatter)
+ else:
+ f = logging.Formatter
+ logger.setFormatter(f(self.section.format, self.section.dateformat))
logger.setLevel(self.section.level)
return logger
Modified: ZConfig/trunk/ZConfig/components/logger/handlers.xml
===================================================================
--- ZConfig/trunk/ZConfig/components/logger/handlers.xml 2006-01-18 21:08:52 UTC (rev 41357)
+++ ZConfig/trunk/ZConfig/components/logger/handlers.xml 2006-01-19 01:43:24 UTC (rev 41358)
@@ -10,6 +10,14 @@
loghandler directly since it doesn't implement the loghandler
abstract section type.
</description>
+ <key name="formatter" datatype="dotted-name" required="no">
+ <description>
+ Logging formatter class. The default is 'logging.Formatter'.
+ An alternative is 'zope.exceptions.log.Formatter',
+ which enhances exception tracebacks with information from
+ __traceback_info__ and __traceback_supplement__ variables.
+ </description>
+ </key>
<key name="dateformat"
default="%Y-%m-%dT%H:%M:%S"/>
<key name="level"
Modified: ZConfig/trunk/ZConfig/components/logger/tests/test_logger.py
===================================================================
--- ZConfig/trunk/ZConfig/components/logger/tests/test_logger.py 2006-01-18 21:08:52 UTC (rev 41357)
+++ ZConfig/trunk/ZConfig/components/logger/tests/test_logger.py 2006-01-19 01:43:24 UTC (rev 41358)
@@ -27,6 +27,18 @@
from ZConfig.components.logger import loghandler
+class CustomFormatter(logging.Formatter):
+ def formatException(self, ei):
+ """Format and return the exception information as a string.
+
+ This adds helpful advice to the end of the traceback.
+ """
+ import traceback
+ sio = StringIO.StringIO()
+ traceback.print_exception(ei[0], ei[1], ei[2], file=sio)
+ return sio.getvalue() + "... Don't panic!"
+
+
class LoggingTestBase(unittest.TestCase):
# XXX This tries to save and restore the state of logging around
@@ -158,6 +170,30 @@
logger.warn("woohoo!")
self.assert_(sio.getvalue().find("woohoo!") >= 0)
+ def test_custom_formatter(self):
+ old_stream = sys.stdout
+ conf = self.get_config("""
+ <eventlog>
+ <logfile>
+ formatter ZConfig.components.logger.tests.test_logger.CustomFormatter
+ level info
+ path STDOUT
+ </logfile>
+ </eventlog>
+ """)
+ sio = StringIO.StringIO()
+ sys.stdout = sio
+ try:
+ logger = conf.eventlog()
+ finally:
+ sys.stdout = old_stream
+ try:
+ raise KeyError
+ except KeyError:
+ logger.exception("testing a KeyError")
+ self.assert_(sio.getvalue().find("KeyError") >= 0)
+ self.assert_(sio.getvalue().find("Don't panic") >= 0)
+
def test_with_syslog(self):
logger = self.check_simple_logger("<eventlog>\n"
" <syslog>\n"
More information about the ZConfig
mailing list