[Zodb-checkins] CVS: ZODB3/zLOG - LogHandlers.py:1.6 component.xml:1.6 datatypes.py:1.8 factory.py:1.3
Fred L. Drake, Jr.
fred@zope.com
Thu, 23 Jan 2003 13:03:09 -0500
Update of /cvs-repository/ZODB3/zLOG
In directory cvs.zope.org:/tmp/cvs-serv21955/zLOG
Modified Files:
LogHandlers.py component.xml datatypes.py factory.py
Log Message:
Change the factory machinery to be a little less ad hoc.
=== ZODB3/zLOG/LogHandlers.py 1.5 => 1.6 ===
--- ZODB3/zLOG/LogHandlers.py:1.5 Thu Jan 23 11:27:13 2003
+++ ZODB3/zLOG/LogHandlers.py Thu Jan 23 13:03:05 2003
@@ -16,7 +16,8 @@
from logging import Handler, StreamHandler
from logging.handlers import SysLogHandler
-from logging.handlers import HTTPHandler, SMTPHandler, NTEventLogHandler
+from logging.handlers import HTTPHandler, SMTPHandler
+from logging.handlers import NTEventLogHandler as Win32EventLogHandler
class FileHandler(StreamHandler):
"""
=== ZODB3/zLOG/component.xml 1.5 => 1.6 ===
--- ZODB3/zLOG/component.xml:1.5 Thu Jan 23 11:57:25 2003
+++ ZODB3/zLOG/component.xml Thu Jan 23 13:03:05 2003
@@ -12,14 +12,14 @@
<key name="level" default="info" datatype=".logging_level"/>
</sectiontype>
- <sectiontype name="logfile" datatype=".file_handler"
+ <sectiontype name="logfile" datatype=".FileHandlerFactory"
implements="loghandler" extends="base-log-handler">
<key name="path" required="yes"/>
<key name="format" default="------\n%(asctime)s %(message)s"
datatype=".log_format"/>
</sectiontype>
- <sectiontype name="syslog" datatype=".syslog_handler"
+ <sectiontype name="syslog" datatype=".SyslogHandlerFactory"
implements="loghandler" extends="base-log-handler">
<key name="facility" default="user" datatype=".syslog_facility"/>
<key name="address" datatype="socket-address" default="localhost:514"/>
@@ -27,14 +27,14 @@
datatype=".log_format"/>
</sectiontype>
- <sectiontype name="win32-eventlog" datatype=".nteventlog_handler"
+ <sectiontype name="win32-eventlog" datatype=".Win32EventLogFactory"
implements="loghandler" extends="base-log-handler">
<key name="appname" default="Zope"/>
<key name="format" default="%(message)s"
datatype=".log_format"/>
</sectiontype>
- <sectiontype name="http-logger" datatype=".http_handler"
+ <sectiontype name="http-logger" datatype=".HTTPHandlerFactory"
implements="loghandler" extends="base-log-handler">
<key name="url" default="http://localhost/" datatype=".http_handler_url"/>
<key name="method" default="GET" datatype=".get_or_post"/>
@@ -42,7 +42,7 @@
datatype=".log_format"/>
</sectiontype>
- <sectiontype name="email-notifier" datatype=".smtp_handler"
+ <sectiontype name="email-notifier" datatype=".SMTPHandlerFactory"
implements="loghandler" extends="base-log-handler">
<key name="from" required="yes" attribute="fromaddr"/>
<multikey name="to" required="yes" attribute="toaddrs"/>
=== ZODB3/zLOG/datatypes.py 1.7 => 1.8 ===
--- ZODB3/zLOG/datatypes.py:1.7 Thu Jan 23 11:57:25 2003
+++ ZODB3/zLOG/datatypes.py Thu Jan 23 13:03:05 2003
@@ -1,6 +1,6 @@
##############################################################################
#
-# 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,
@@ -75,24 +75,32 @@
value = value.replace(pattern, replacement)
return value
-def file_handler(section):
- path = section.path
- def callback(inst,
- format=section.format,
- dateformat=section.dateformat,
- level=section.level):
- import logging
- inst.setFormatter(logging.Formatter(format, dateformat))
- inst.setLevel(level)
+class HandlerFactory(Factory):
+ def __init__(self, section):
+ Factory.__init__(self)
+ self.section = section
- # XXX should pick up sys.{stderr,stdout} when the factory is invoked
- if path == "STDERR":
- return Factory('zLOG.LogHandlers.StreamHandler', callback, sys.stderr)
- elif path == "STDOUT":
- return Factory('zLOG.LogHandlers.StreamHandler', callback, sys.stdout)
- else:
- return Factory('zLOG.LogHandlers.FileHandler', callback, path)
+ def create_logger(self):
+ raise NotImplementedError("subclasses must override create_logger()")
+
+ def create(self):
+ import logging
+ logger = self.create_logger()
+ logger.setFormatter(logging.Formatter(self.section.format,
+ self.section.dateformat))
+ logger.setLevel(self.section.level)
+ return logger
+
+class FileHandlerFactory(HandlerFactory):
+ def create_logger(self):
+ from zLOG.LogHandlers import StreamHandler, FileHandler
+ path = self.section.path
+ if path == "STDERR":
+ return StreamHandler(sys.stderr)
+ if path == "STDOUT":
+ return StreamHandler(sys.stdout)
+ return FileHandler(path)
_syslog_facilities = {
"auth": 1,
@@ -125,30 +133,16 @@
raise ValueError("Syslog facility must be one of " + ", ".join(L))
return value
-def syslog_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.SysLogHandler', callback,
- section.address.address,
- section.facility)
-
-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,
- section.appname)
+class SyslogHandlerFactory(HandlerFactory):
+ def create_logger(self):
+ from zLOG.LogHandlers import SysLogHandler
+ return SysLogHandler(self.section.address.address,
+ self.section.facility)
+
+class Win32EventLogFactory(HandlerFactory):
+ def create_logger(self):
+ from zLOG.LogHandlers import Win32EventLogHandler
+ return Win32EventLogHandler(self.section.appname)
def http_handler_url(value):
import urlparse
@@ -178,45 +172,25 @@
+ repr(value))
return value
-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)
-
- host, selector = section.url
- return Factory('zLOG.LogHandlers.HTTPHandler',
- callback, host, selector, section.method)
-
-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)
-
- host, port = section.smtp_server
- if not port:
- mailhost = host
- else:
- mailhost = host, port
-
- return Factory('zLOG.LogHandlers.SMTPHandler',
- callback,
- mailhost,
- section.fromaddr,
- section.toaddrs,
- section.subject)
+class HTTPHandlerFactory(HandlerFactory):
+ def create_logger(self):
+ from zLOG.LogHandlers import HTTPHandler
+ host, selector = self.section.url
+ return HTTPHandler(host, selector, self.section.method)
+
+class SMTPHandlerFactory(HandlerFactory):
+ def create_logger(self):
+ from zLOG.LogHandlers import SMTPHandler
+ host, port = self.section.smtp_server
+ if not port:
+ mailhost = host
+ else:
+ mailhost = host, port
+ return SMTPHandler(mailhost, self.section.fromaddr,
+ self.section.toaddrs, self.section.subject)
-_marker = []
-
-class EventLogFactory:
+class EventLogFactory(Factory):
"""
A wrapper used to create loggers while delaying actual logger
instance construction. We need to do this because we may
@@ -226,24 +200,22 @@
logger object.
"""
def __init__(self, section):
+ Factory.__init__(self)
self.level = section.level
self.handler_factories = section.handlers
- self.resolved = _marker
- def __call__(self):
- if self.resolved is _marker:
- # set the logger up
- import logging
- logger = logging.getLogger("event")
- logger.handlers = []
- logger.propagate = 0
- logger.setLevel(self.level)
- if self.handler_factories:
- for handler_factory in self.handler_factories:
- handler = handler_factory()
- logger.addHandler(handler)
- else:
- from zLOG.LogHandlers import NullHandler
- logger.addHandler(NullHandler())
- self.resolved = logger
- return self.resolved
+ def create(self):
+ # set the logger up
+ import logging
+ logger = logging.getLogger("event")
+ logger.handlers = []
+ logger.propagate = 0
+ logger.setLevel(self.level)
+ if self.handler_factories:
+ for handler_factory in self.handler_factories:
+ handler = handler_factory()
+ logger.addHandler(handler)
+ else:
+ from zLOG.LogHandlers import NullHandler
+ logger.addHandler(NullHandler())
+ return logger
=== ZODB3/zLOG/factory.py 1.2 => 1.3 ===
--- ZODB3/zLOG/factory.py:1.2 Mon Jan 20 17:40:07 2003
+++ ZODB3/zLOG/factory.py Thu Jan 23 13:03:05 2003
@@ -14,45 +14,23 @@
_marker = []
-def importer(name):
- components = name.split('.')
- start = components[0]
- g = globals()
- package = __import__(start, g, g)
- modulenames = [start]
- for component in components[1:]:
- modulenames.append(component)
- try:
- package = getattr(package, component)
- except AttributeError:
- name = '.'.join(modulenames)
- package = __import__(name, g, g, component)
- return package
-
class Factory:
+ """Generic wrapper for instance construction.
+
+ Calling the factory causes the instance to be created if it hasn't
+ already been created, and returns the object. Calling the factory
+ multiple times returns the same object.
+
+ The instance is created using the factory's create() method, which
+ must be overriden by subclasses.
"""
- A generic wrapper for instance construction and function calling used
- to delay construction/call until necessary. The class path is the dotted
- name to the class or function, args are the positional args, kw are the
- keyword args. If it is specified, 'callback' is a function which will be
- called back after constructing an instance or calling a function. It must
- take the instance (or the result of the function) as a single argument.
- """
- def __init__(self, class_path, callback, *args, **kw):
- self.class_path = class_path
- self.callback = callback
- self.args = args
- self.kw = kw
+ def __init__(self):
self.instance = _marker
- def __repr__(self):
- return ('<Factory instance for class "%s" with positional args "%s" '
- 'and keword args "%s"' % (self.class_path, self.args, self.kw))
-
def __call__(self):
if self.instance is _marker:
- constructor = importer(self.class_path)
- self.instance = constructor(*self.args, **self.kw)
- if self.callback is not None:
- self.callback(self.instance)
+ self.instance = self.create()
return self.instance
+
+ def create(self):
+ raise NotImplementedError("subclasses need to override create()")