[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()")