Commit e5cd306e authored by Fred Drake's avatar Fred Drake

- re-enable several loghandler types

- make it easier for an admin to configure logging levels
  (by making the defaults more sane)
- refactor the tests a little, in preparation for more tests
parent 9ef37bd4
......@@ -2,60 +2,57 @@
<abstracttype name="loghandler"/>
<sectiontype name="file-handler" datatype=".file_handler"
implements="loghandler">
<sectiontype name="base-log-handler">
<description>
Base type for most log handlers. This is cannot be used as a
loghandler directly since it doesn't implement the loghandler
abstract section type.
</description>
<key name="dateformat" default="%Y-%m-%dT%H:%M:%S"/>
<key name="level" default="info" datatype=".logging_level"/>
</sectiontype>
<sectiontype name="logfile" datatype=".file_handler"
implements="loghandler" extends="base-log-handler">
<key name="path" required="yes"/>
<key name="format" default="------\n%(asctime)s %(message)s"
datatype=".log_format"/>
<key name="dateformat" default="%Y-%m-%dT%H:%M:%S"/>
<key name="level" default="info" datatype=".logging_level"/>
</sectiontype>
<sectiontype name="syslog-handler" datatype=".syslog_handler"
implements="loghandler">
<sectiontype name="syslog" datatype=".syslog_handler"
implements="loghandler" extends="base-log-handler">
<key name="facility" default="user" datatype=".syslog_facility"/>
<key name="address" datatype="socket-address" required="yes"/>
<key name="format" default="%(message)s"
datatype=".log_format"/>
<key name="dateformat" default="%Y-%m-%dT%H:%M:%S"/>
<key name="level" default="info" datatype=".logging_level"/>
</sectiontype>
<!--
<sectiontype name="nteventlog_handler" datatype=".nteventlog_handler"
implements="loghandler">
<sectiontype name="nteventlog" datatype=".nteventlog_handler"
implements="loghandler" extends="base-log-handler">
<key name="appname" default="Zope"/>
<key name="format" default="%(message)s"
datatype=".log_format"/>
<key name="dateformat" default="%Y-%m-%dT%H:%M:%S"/>
<key name="level" default="info" datatype=".logging_level"/>
</sectiontype>
<sectiontype name="http_handler" datatype=".http_handler"
implements="loghandler">
implements="loghandler" extends="base-log-handler">
<key name="url" default="localhost" datatype=".http_handler_url"/>
<key name="method" default="GET" datatype=".get_or_post"/>
<key name="format" default="%(asctime)s %(message)s"
datatype=".log_format"/>
<key name="dateformat" default="%Y-%m-%dT%H:%M:%S"/>
<key name="level" default="info" datatype=".logging_level"/>
</sectiontype>
<sectiontype name="smtp_handler" datatype=".smtp_handler"
implements="loghandler">
implements="loghandler" extends="base-log-handler">
<key name="fromaddr" required="yes"/>
<multikey name="toaddr" required="yes" attribute="toaddrs"/>
<key name="subject" default="Message from Zope"/>
<key name="host" default="localhost" datatype="inet-address"/>
<key name="format" default="%(asctime)s %(message)s"
datatype=".log_format"/>
<key name="dateformat" default="%Y-%m-%dT%H:%M:%S"/>
<key name="level" default="info" datatype=".logging_level"/>
</sectiontype>
<sectiontype name="null_handler" datatype=".null_handler"
implements="loghandler"/>
<!--
<sectiontype name="custom_handler" datatype=".custom_handler"
implements="loghandler">
<key name="constructor" datatype="constructor" required="yes"/>
......@@ -66,7 +63,7 @@
-->
<sectiontype name="logger" datatype=".logger">
<key name="level" datatype=".logging_level" default="info"/>
<key name="level" datatype=".logging_level" default="all"/>
<multisection type="loghandler" attribute="handlers" name="*"/>
</sectiontype>
......
......@@ -136,84 +136,80 @@ def syslog_handler(section):
section.address.address,
section.facility)
## def nteventlog_handler(section):
## appname = section.appname
## format = section.format
## dateformat = section.dateformat
## level = section.level
## formatter = Factory('logging.Formatter', None, format, dateformat)
## def callback(inst, formatter=formatter, level=level):
## inst.setFormatter(formatter())
## inst.setLevel(level)
def nteventlog_handler(section):
def callback(inst,
format=section.format,
dateformat=section.dateformat,
level=section.level):
import logging
inst.setFormatter(logging.Formatter(format, dateformat))
inst.setLevel(level)
## return Factory('zLOG.LogHandlers.NTEventLogHandler', callback, appname)
## def http_handler_url(value):
## import urlparse
## scheme, netloc, path, query, fragment = urlparse.urlsplit(value)
## if scheme != 'http':
## raise ValueError, 'url must be an http url'
## if not netloc:
## raise ValueError, 'url must specify a location'
## if not path:
## raise ValueError, 'url must specify a path'
## q = []
## if query:
## q.append('?')
## q.append(query)
## if fragment:
## q.append('#')
## q.append(fragment)
## return (netloc, path + ''.join(q))
## def get_or_post(value):
## value = value.upper()
## if value not in ('GET', 'POST'):
## raise ValueError, ('method must be "GET" or "POST", instead received '
## '%s' % repr(value))
## return value
## def http_handler(section):
## host, url = section.url
## method = section.method
## format = section.format
## dateformat = section.dateformat
## level = section.level
## formatter = Factory('logging.Formatter', None, format, dateformat)
return Factory('zLOG.LogHandlers.NTEventLogHandler', callback,
section.appname)
def http_handler_url(value):
import urlparse
scheme, netloc, path, param, query, fragment = urlparse.urlparse(value)
if scheme != 'http':
raise ValueError, 'url must be an http url'
if not netloc:
raise ValueError, 'url must specify a location'
if not path:
raise ValueError, 'url must specify a path'
q = []
if param:
q.append(';')
q.append(param)
if query:
q.append('?')
q.append(query)
if fragment:
q.append('#')
q.append(fragment)
return (netloc, path + ''.join(q))
def get_or_post(value):
value = value.upper()
if value not in ('GET', 'POST'):
raise ValueError('method must be "GET" or "POST", instead received: '
+ repr(value))
return value
## def callback(inst, formatter=formatter, level=level):
## inst.setFormatter(formatter())
## inst.setLevel(level)
def http_handler(section):
def callback(inst,
format=section.format,
dateformat=section.dateformat,
level=section.level):
import logging
inst.setFormatter(logging.Formatter(format, dateformat))
inst.setLevel(level)
## return Factory('zLOG.LogHandlers.HTTPHandler', callback, host, url, method)
## def smtp_handler(section):
## fromaddr = section.fromaddr
## toaddrs = section.toaddrs
## subject = section.subject
## host, port = section.host
## format = section.format
## dateformat = section.dateformat
## level = section.level
## if not port:
## mailhost = host
## else:
## mailhost = host, port
## formatter = Factory('logging.Formatter', None, format, dateformat)
host, selector = section.url
return Factory('zLOG.LogHandlers.HTTPHandler',
callback, host, selector, section.method)
## def callback(inst, formatter=formatter, level=level):
## inst.setFormatter(formatter())
## inst.setLevel(level)
def smtp_handler(section):
def callback(inst,
format=section.format,
dateformat=section.dateformat,
level=section.level):
import logging
inst.setFormatter(logging.Formatter(format, dateformat))
inst.setLevel(level)
## return Factory('zLOG.LogHandlers.SMTPHandler', callback,
## mailhost, fromaddr, toaddrs, subject)
host, port = section.host
if not port:
mailhost = host
else:
mailhost = host, port
## def null_handler(section):
## return Factory('zLOG.LogHandlers.NullHandler', None)
return Factory('zLOG.LogHandlers.SMTPHandler',
callback,
mailhost,
section.fromaddr,
section.toaddrs,
section.subject)
## def custom_handler(section):
## formatter_klass, formatter_pos, formatter_kw = section.formatter
......@@ -257,7 +253,7 @@ class LoggerWrapper:
logger.setLevel(self.level)
if self.handler_factories:
for handler_factory in self.handler_factories:
handler = handler_factory()
handler = handler_factory()
logger.addHandler(handler)
else:
from zLOG.LogHandlers import NullHandler
......
##############################################################################
#
# Copyright (c) 2002, 2003 Zope Corporation and Contributors.
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
......@@ -16,6 +16,7 @@
import cStringIO as StringIO
import logging
import tempfile
import unittest
import ZConfig
......@@ -64,19 +65,39 @@ class TestzLOGConfig(unittest.TestCase):
self.assert_(conf.logger is None)
def test_config_without_handlers(self):
conf = self.get_config("<logger/>")
self.assert_(conf.logger is not None)
self.assertEqual(conf.logger.level, logging.INFO)
logger = conf.logger()
self.assert_(isinstance(logger, logging.Logger))
logger = self.check_simple_logger("<logger/>")
# Make sure there's a NullHandler, since a warning gets
# printed if there are no handlers:
self.assertEqual(len(logger.handlers), 1)
self.assert_(isinstance(logger.handlers[0],
zLOG.LogHandlers.NullHandler))
def test_with_logfile(self):
fn = tempfile.mktemp()
logger = self.check_simple_logger("<logger>\n"
" <logfile>\n"
" path %s\n"
" level debug\n"
" </logfile>\n"
"</logger>" % fn)
# Make sure there's exactly one handler, since a warning gets
# printed if there are no handlers, and we don't want an
# unnecessary NullHandler getting added:
self.assertEqual(len(logger.handlers), 1)
self.assertEqual(logger.handlers[0].level, logging.DEBUG)
self.assert_(isinstance(logger.handlers[0],
zLOG.LogHandlers.FileHandler))
# XXX need to make sure each loghandler datatype gets exercised.
def check_simple_logger(self, text, level=logging.NOTSET):
conf = self.get_config(text)
self.assertEqual(conf.logger.level, level)
self.assert_(conf.logger is not None)
logger = conf.logger()
self.assert_(isinstance(logger, logging.Logger))
return logger
def test_suite():
return unittest.makeSuite(TestzLOGConfig)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment