[Zope-CVS] CVS: Packages/Startup - datatypes.py:1.3 handlers.py:1.3 main.py:1.2 zopeschema.xml:1.3

Chris McDonough chrism@zope.com
Fri, 3 Jan 2003 00:46:52 -0500


Update of /cvs-repository/Packages/Startup
In directory cvs.zope.org:/tmp/cvs-serv20570

Modified Files:
	datatypes.py handlers.py main.py zopeschema.xml 
Log Message:
Rework logger sections to not require Python-style constructors.


=== Packages/Startup/datatypes.py 1.2 => 1.3 ===
--- Packages/Startup/datatypes.py:1.2	Thu Jan  2 11:41:12 2003
+++ Packages/Startup/datatypes.py	Fri Jan  3 00:46:18 2003
@@ -1,7 +1,7 @@
-# log-related datatypes
-
 from misc.factory import Factory
 
+# generic datatypes
+
 def security_policy_implementation(value):
     value = value.upper()
     ok = ('PYTHON', 'C')
@@ -11,14 +11,211 @@
             )
     return value
 
-def handler(section):
+# log-related datatypes
+
+def log_format(value):
+    d = {
+        'name':'',
+        'levelno':'3',
+        'levelname':'DEBUG',
+        'pathname':'apath',
+        'filename':'afile',
+        'module':'amodule',
+        'lineno':1,
+        'created':1.1,
+        'asctime':'atime',
+        'msecs':1,
+        'relativeCreated':1,
+        'thread':1,
+        'message':'amessage',
+        }
+    try:
+        value % d
+    except (ValueError, KeyError):
+        raise ValueError, 'Invalid log format string %s' % value
+    value = ctrl_char_insert(value)
+    return value
+
+def ctrl_char_insert(value):
+    chars = {r'\n':'\n', r'\t':'\t', r'\b':'\b', r'\f':'\f', r'\r':'\r'}
+    realvalue = value
+    for char in chars.keys():
+        l = realvalue.split(char)
+        realvalue = chars[char].join(l)
+    return realvalue
+
+def file_handler(section):
+    file       = section.file
+    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)
+
+    return Factory('zLOG.LogHandlers.FileHandler', callback,
+                   *[file], **{})
+
+def syslog_facility(value):
+    d = {
+        "auth":1,
+        "authpriv":1,
+        "cron":1,
+        "daemon":1,
+        "kern":1,
+        "lpr":1,
+        "mail":1,
+        "news":1,
+        "security":1,
+        "syslog":1,
+        "user":1,
+        "uucp":1,
+        "local0":1,
+        "local1":1,
+        "local2":1,
+        "local3":1,
+        "local4":1,
+        "local5":1,
+        "local6":1,
+        "local7":1,
+        }
+    value = value.lower()
+    if not d.has_key(value):
+        raise ValueError, "Syslog facility must be one of %s" % d.keys()
+    return value
+
+def syslog_handler(section):
+    facility = section.facility
+    socket = section.socket
+    host = section.host
+    port = section.port
+    format = section.format
+    dateformat = section.dateformat
+    level = section.level
+
+    if socket and host:
+        raise ValueError, ('Only one of "socket" or "host" may be '
+                           'specified in a syslog_handler section')
+    if not (socket or host):
+        raise ValueError, ('One of "socket" or "host" must be '
+                           'specified in a syslog_handler section')
+        
+    formatter = Factory('logging.Formatter', None,
+                        *[format, dateformat], **{})
+
+    def callback(inst, formatter=formatter, level=level):
+        inst.setFormatter(formatter())
+        inst.setLevel(level)
+
+    klass = 'zLOG.LogHandlers.SysLogHandler'
+    if socket:
+        handler = Factory(klass, callback, *[socket, facility], **{})
+    else:
+        handler = Factory(klass, callback, *[(host, port), facility],
+                          **{})
+
+    return handler
+
+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)
+
+    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' % 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], **{})
+
+    def callback(inst, formatter=formatter, level=level):
+        inst.setFormatter(formatter())
+        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], **{})
+
+    def callback(inst, formatter=formatter, level=level):
+        inst.setFormatter(formatter())
+        inst.setLevel(level)
+
+    return Factory('zLOG.LogHandlers.SMTPHandler', callback,
+                   *[mailhost, fromaddr, toaddrs, subject], **{})
+
+def null_handler(section):
+    return Factory('zLOG.LogHandlers.NullHandler', None)
+
+def custom_handler(section):
     formatter_klass, formatter_pos, formatter_kw = section.formatter
     handler_klass, handler_pos, handler_kw = section.constructor
+    level = section.level
+
     formatter = Factory(formatter_klass, None, formatter_pos, formatter_kw)
-    def handler_callback(inst, formatter=formatter):
-        formatter = formatter()
-        inst.setFormatter(formatter)
-    return Factory(handler_klass, handler_callback, *handler_pos, **handler_kw)
+
+    def callback(inst, formatter=formatter, level=level):
+        inst.setFormatter(formatter())
+        inst.setLevel(level)
+
+    return Factory(handler_klass, callback, *handler_pos, **handler_kw)
 
 def logger(section):
     return LoggerWrapper(section.__name__, section.level, section.handlers)


=== Packages/Startup/handlers.py 1.2 => 1.3 ===
--- Packages/Startup/handlers.py:1.2	Thu Jan  2 11:41:12 2003
+++ Packages/Startup/handlers.py	Fri Jan  3 00:46:18 2003
@@ -77,7 +77,8 @@
     return value
 
 def maximum_number_of_session_objects(value):
-    value is not None and _setenv('ZSESSION_OBJECT_LIMIT', value)
+    default = 1000
+    value not in (None, default) and _setenv('ZSESSION_OBJECT_LIMIT', value)
     return value
 
 def session_add_notify_script_path(value):
@@ -89,7 +90,8 @@
     return value
 
 def session_timeout_minutes(value):
-    value is not None and _setenv('ZSESSION_TIMEOUT_MINS', value)
+    default = 20
+    value not in (None, default) and _setenv('ZSESSION_TIMEOUT_MINS', value)
     return value
 
 def suppress_all_access_rules(value):
@@ -133,21 +135,17 @@
 
 # server handlers
 
-class _SchemaHandler:
-    _done = 0
-    
+class _RootHandler:
     def __call__(self, config):
         """ Mutate the configuration with defaults and perform
         fixups of values that require knowledge about configuration
         values outside of their context. """
 
         self._config = config
-        if self._done: # only do this once
-            return
 
         # alias some things for use in server handlers
-        from zLOG.AccessLogger import AccessLogger
-        self._logger = AccessLogger
+        from zLOG.AccessLogger import access_logger
+        self._logger = access_logger
         import ZODB # :-( required to import user
         from AccessControl.User import emergency_user
         if hasattr(emergency_user, '__null_user__'):
@@ -220,9 +218,6 @@
             dbfactory = Factory('ZODB.DB', None, *[], **{})
             databases.append((['/'], DBWrapper(dbfactory, storagefactory)))
 
-        # finish
-        self._done = 1
-
     def get_dns_resolver(self):
         if self._config.dns_ip_address:
             from ZServer import resolver
@@ -322,7 +317,7 @@
             l.append(serverfactory)
         return l
 
-schema = _SchemaHandler()
+root_handler = _RootHandler()
 
 def handleConfig(config, multihandler):
     handlers = {}


=== Packages/Startup/main.py 1.1.1.1 => 1.2 ===
--- Packages/Startup/main.py:1.1.1.1	Wed Jan  1 06:05:40 2003
+++ Packages/Startup/main.py	Fri Jan  3 00:46:18 2003
@@ -36,7 +36,11 @@
     # set up our initial logging environment (log everything to stderr
     # if we're not in debug mode).
     import zLOG
+
+    # don't initialize the event logger from the environment
+    zLOG._call_initialize = 0
     import logging
+    
     from zLOG.LogHandlers import StartupHandler
 
     # we log events to the root logger, which is backed by a
@@ -45,7 +49,8 @@
     # are set up, we flush accumulated messages in StartupHandler's
     # buffers to the real logger.
     startup_handler = StartupHandler(sys.stderr)
-
+    formatter = zLOG.EventLogger.formatters['file']
+    startup_handler.setFormatter(formatter)
     if not cfg.debug_mode:
         # prevent startup messages from going to stderr if we're not
         # in debug mode
@@ -55,9 +60,9 @@
             devnull = 'nul:'
         startup_handler = StartupHandler(open(devnull, 'w'))
 
-    # set up our root logger only (others will propagate)
-    logger = logging.getLogger('')
-    logger.addHandler(startup_handler)
+    # set up our event logger temporarily with a startup handler
+    event_logger = logging.getLogger('event')
+    event_logger.addHandler(startup_handler)
 
     # set a locale if one has been specified in the config
     cfg.locale and do_locale(cfg.locale)
@@ -143,16 +148,18 @@
             if factory:
                 logger = factory() # activate the logger
                 # flush buffered startup messages to event logger
-                if logger_name == 'event_logger':
+                if logger_name == 'event':
                     startup_handler.flushBufferTo(logger)
 
+        event_logger.removeHandler(startup_handler)
+
     zLOG.LOG('Zope', zLOG.INFO, 'Ready to handle requests')
 
     # Start Medusa, Ye Hass!
     sys.ZServerExitCode=0
     try:
-        import asyncore
-        asyncore.loop()
+        import Lifetime
+        Lifetime.loop()
         sys.exit(sys.ZServerExitCode)
     finally:
         if not cfg.zserver_read_only_mode:


=== Packages/Startup/zopeschema.xml 1.2 => 1.3 ===
--- Packages/Startup/zopeschema.xml:1.2	Thu Jan  2 11:41:12 2003
+++ Packages/Startup/zopeschema.xml	Fri Jan  3 00:46:18 2003
@@ -1,11 +1,67 @@
-<schema prefix="Startup.datatypes" handler="schema">
+<schema prefix="Startup.datatypes" handler="root_handler">
 
   <!-- type definitions -->
 
-  <sectiontype type="handler" datatype=".handler">
-    <key name="constructor" datatype="constructor" required="yes"/>
-    <key name="formatter" datatype="constructor" default="logging.Formatter()"/>
-  </sectiontype>
+  <sectiongroup type="handler">
+
+    <sectiontype type="file_handler" datatype=".file_handler">
+      <key name="file" 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 type="syslog_handler" datatype=".syslog_handler">
+      <key name="facility" default="user" datatype=".syslog_facility"/>
+      <key name="socket" datatype="existing-file"/>
+      <key name="port" default="514" datatype="port-number"/>
+      <key name="host" datatype="ipaddr-or-hostname"/>
+      <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 type="nteventlog_handler" datatype=".nteventlog_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 type="http_handler" datatype=".http_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 type="smtp_handler" datatype=".smtp_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 type="null_handler" datatype=".null_handler">
+    </sectiontype>
+
+    <sectiontype type="custom_handler" datatype=".custom_handler">
+      <key name="constructor" datatype="constructor" required="yes"/>
+      <key name="formatter" datatype="constructor"
+           default="logging.Formatter()"/>
+      <key name="level" default="info" datatype="logging-level"/>
+    </sectiontype>
+
+  </sectiongroup>
 
   <sectiontype type="logger" datatype=".logger">
      <key name="level" datatype="logging-level" default="info"/>