[Zodb-checkins] CVS: Packages/SFTPGateway/src/ZConfig/components/logger - __init__.py:1.1 abstract.xml:1.1 component.xml:1.1 datatypes.py:1.1 factory.py:1.1 handlers.py:1.1 handlers.xml:1.1 logger.py:1.1 logger.xml:1.1 loghandler.py:1.1

Fred L. Drake, Jr. fred at zope.com
Fri Jan 2 13:46:17 EST 2004


Update of /cvs-repository/Packages/SFTPGateway/src/ZConfig/components/logger
In directory cvs.zope.org:/tmp/cvs-serv10272/logger

Added Files:
	__init__.py abstract.xml component.xml datatypes.py factory.py 
	handlers.py handlers.xml logger.py logger.xml loghandler.py 
Log Message:
configuration support for the "logging" package, separate from zLOG


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/__init__.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ZConfig schema component package for logging configuration."""

# Make sure we can't import this if "logging" isn't available; we
# don't want partial imports to appear to succeed.

try:
    import logging
except ImportError:
    import sys
    del sys.modules[__name__]


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/abstract.xml ===
<component>
  <description>
  </description>

  <abstracttype name="ZConfig.logger.handler"/>
  <abstracttype name="ZConfig.logger.log"/>
</component>


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/component.xml ===
<component prefix="ZConfig.components.logger.datatypes">
  <description>
  </description>

  <import package="ZConfig.components.logger" file="abstract.xml"/>
  <import package="ZConfig.components.logger" file="handlers.xml"/>
  <import package="ZConfig.components.logger" file="logger.xml"/>

</component>


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/datatypes.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################

"""ZConfig datatypes for logging support."""


_logging_levels = {
    "critical": 50,
    "fatal": 50,
    "error": 40,
    "warn": 30,
    "warning": 30,
    "info": 20,
    "blather": 15,
    "debug": 10,
    "trace": 5,
    "all": 1,
    "notset": 0,
    }

def logging_level(value):
    s = str(value).lower()
    if _logging_levels.has_key(s):
        return _logging_levels[s]
    else:
        v = int(s)
        if v < 0 or v > 50:
            raise ValueError("log level not in range: " + `v`)
        return v


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/factory.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################

_marker = []

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.
    """
    def __init__(self):
        self.instance = _marker

    def __call__(self):
        if self.instance is _marker:
            self.instance = self.create()
        return self.instance

    def create(self):
        raise NotImplementedError("subclasses need to override create()")


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/handlers.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ZConfig factory datatypes for log handlers."""

import sys

from ZConfig.components.logger.factory import Factory


_log_format_variables = {
    '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',
    }

def log_format(value):
    value = ctrl_char_insert(value)
    try:
        # Make sure the format string uses only names that will be
        # provided, and has reasonable type flags for each, and does
        # not expect positional args.
        value % _log_format_variables
    except (ValueError, KeyError):
        raise ValueError, 'Invalid log format string %s' % value
    return value

_control_char_rewrites = {r'\n': '\n', r'\t': '\t', r'\b': '\b',
                          r'\f': '\f', r'\r': '\r'}.items()

def ctrl_char_insert(value):
    for pattern, replacement in _control_char_rewrites:
        value = value.replace(pattern, replacement)
    return value


class HandlerFactory(Factory):
    def __init__(self, section):
        Factory.__init__(self)
        self.section = section

    def create_loghandler(self):
        raise NotImplementedError(
            "subclasses must override create_loghandler()")

    def create(self):
        import logging
        logger = self.create_loghandler()
        logger.setFormatter(logging.Formatter(self.section.format,
                                              self.section.dateformat))
        logger.setLevel(self.section.level)
        return logger

    def getLevel(self):
        return self.section.level

class FileHandlerFactory(HandlerFactory):
    def create_loghandler(self):
        from ZConfig.components.logger import loghandler
        path = self.section.path
        if path == "STDERR":
            return loghandler.StreamHandler(sys.stderr)
        if path == "STDOUT":
            return loghandler.StreamHandler(sys.stdout)
        return loghandler.FileHandler(path)

_syslog_facilities = {
    "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,
    }

def syslog_facility(value):
    value = value.lower()
    if not _syslog_facilities.has_key(value):
        L = _syslog_facilities.keys()
        L.sort()
        raise ValueError("Syslog facility must be one of " + ", ".join(L))
    return value

class SyslogHandlerFactory(HandlerFactory):
    def create_loghandler(self):
        from ZConfig.components.logger import loghandler
        return loghandler.SysLogHandler(self.section.address.address,
                                        self.section.facility)

class Win32EventLogFactory(HandlerFactory):
    def create_loghandler(self):
        from ZConfig.components.logger import loghandler
        return loghandler.Win32EventLogHandler(self.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

class HTTPHandlerFactory(HandlerFactory):
    def create_loghandler(self):
        from ZConfig.components.logger import loghandler
        host, selector = self.section.url
        return loghandler.HTTPHandler(host, selector, self.section.method)

class SMTPHandlerFactory(HandlerFactory):
    def create_loghandler(self):
        from ZConfig.components.logger import loghandler
        host, port = self.section.smtp_server
        if not port:
            mailhost = host
        else:
            mailhost = host, port
        return loghandler.SMTPHandler(mailhost,
                                      self.section.fromaddr,
                                      self.section.toaddrs,
                                      self.section.subject)


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/handlers.xml ===
<component prefix="ZConfig.components.logger.handlers">
  <description>
  </description>

  <import package="ZConfig.components.logger" file="abstract.xml"/>

  <sectiontype name="ZConfig.logger.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="notset"
         datatype="ZConfig.components.logger.datatypes.logging_level"/>
  </sectiontype>

  <sectiontype name="logfile"
               datatype=".FileHandlerFactory"
               implements="ZConfig.logger.handler"
               extends="ZConfig.logger.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=".SyslogHandlerFactory"
               implements="ZConfig.logger.handler"
               extends="ZConfig.logger.base-log-handler">
    <key name="facility" default="user" datatype=".syslog_facility"/>
    <key name="address" datatype="socket-address" default="localhost:514"/>
    <key name="format" default="%(message)s"
         datatype=".log_format"/>
  </sectiontype>

  <sectiontype name="win32-eventlog"
               datatype=".Win32EventLogFactory"
               implements="ZConfig.logger.handler"
               extends="ZConfig.logger.base-log-handler">
    <key name="appname" default="Zope"/>
    <key name="format" default="%(message)s"
         datatype=".log_format"/>
  </sectiontype>

  <sectiontype name="http-logger"
               datatype=".HTTPHandlerFactory"
               implements="ZConfig.logger.handler"
               extends="ZConfig.logger.base-log-handler">
    <key name="url" default="http://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"/>
  </sectiontype>

  <sectiontype name="email-notifier"
               datatype=".SMTPHandlerFactory"
               implements="ZConfig.logger.handler"
               extends="ZConfig.logger.base-log-handler">
    <key name="from" required="yes" attribute="fromaddr"/>
    <multikey name="to" required="yes" attribute="toaddrs"/>
    <key name="subject" default="Message from Zope"/>
    <key name="smtp-server" default="localhost" datatype="inet-address"/>
    <key name="format" default="%(asctime)s %(message)s"
         datatype=".log_format"/>
  </sectiontype>

</component>


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/logger.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ZConfig factory datatypes for loggers."""

from ZConfig.components.logger.factory import Factory


class LoggerFactoryBase(Factory):

    def __init__(self, section):
        Factory.__init__(self)
        self.level = section.level
        self.handler_factories = section.handlers

    def create(self):
        # set the logger up
        import logging
        logger = logging.getLogger(self.name)
        logger.handlers = []
        logger.setLevel(self.level)
        if self.handler_factories:
            for handler_factory in self.handler_factories:
                handler = handler_factory()
                logger.addHandler(handler)
        else:
            from ZConfig.components.logger import loghandler
            logger.addHandler(loghandler.NullHandler())
        return logger

    def startup(self):
        # make sure we've instantiated the logger
        self()


class EventLogFactory(LoggerFactoryBase):
    """
    A wrapper used to create loggers while delaying actual logger
    instance construction.  We need to do this because we may
    want to reference a logger before actually instantiating it (for example,
    to allow the app time to set an effective user).
    An instance of this wrapper is a callable which, when called, returns a
    logger object.
    """

    name = "event"

    def create(self):
        logger = LoggerFactoryBase.create(self)
        logger.propagate = 0
        return logger


class LoggerFactory(LoggerFactoryBase):

    def __init__(self, section):
        LoggerFactoryBase.__init__(self, section)
        self.name = section.name
        self.propagate = section.propagate

    def create(self):
        logger = LoggerFactoryBase.create(self)
        logger.propagate = self.propagate
        return logger


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/logger.xml ===
<component prefix="ZConfig.components.logger.logger">
  <description>
  </description>

  <import package="ZConfig.components.logger" file="abstract.xml"/>

  <sectiontype name="ZConfig.logger.base-logger">
     <key name="level"
          datatype="ZConfig.components.logger.datatypes.logging_level"
          default="info"/>
     <multisection type="ZConfig.logger.handler"
                   attribute="handlers" name="*"/>
  </sectiontype>

  <sectiontype name="logger"
               datatype=".LoggerFactory"
               extends="ZConfig.logger.base-logger">
    <key name="propagate"
         datatype="boolean"
         default="true">
      <description>
      </description>
    </key>

    <key name="name"
         datatype="dotted-name"
         required="yes">
      <description>
      </description>
    </key>
  </sectiontype>

  <sectiontype name="eventlog"
               datatype=".EventLogFactory"
               extends="ZConfig.logger.base-logger">
    <description>
      Logger bound to the name "event".  Propogation of events to the
      root logger is disabled.
    </description>
  </sectiontype>

</component>


=== Added File Packages/SFTPGateway/src/ZConfig/components/logger/loghandler.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################

"""Handlers which can plug into a PEP 282 logger."""

import sys

from logging import Handler, StreamHandler
from logging.handlers import SysLogHandler
from logging.handlers import HTTPHandler, SMTPHandler
from logging.handlers import NTEventLogHandler as Win32EventLogHandler


class FileHandler(StreamHandler):
    """File handler which supports reopening of logs.

    Re-opening should be used instead of the 'rollover' feature of
    the FileHandler from the standard library's logging package.
    """

    def __init__(self, filename, mode="a"):
        StreamHandler.__init__(self, open(filename, mode))
        self.baseFilename = filename
        self.mode = mode

    def close(self):
        self.stream.close()

    def reopen(self):
        self.close()
        self.stream = open(self.baseFilename, self.mode)


class NullHandler(Handler):
    """Handler that does nothing."""

    def emit(self, record):
        pass

    def handle(self, record):
        pass


class StartupHandler(Handler):
    """
    A handler which outputs messages to a stream but also buffers them until
    they can be flushed to a target handler.  Useful at startup before we can
    know that we can safely write to a config-specified handler.
    """
    def __init__(self, stream=None):
        Handler.__init__(self)
        if not stream:
            stream = sys.stderr
        self.stream = stream
        self.buffer = []

    def emit(self, record):
        try:
            self.buffer.append(record)
            msg = self.format(record)
            self.stream.write("%s\n" % msg)
            self.flush()
        except:
            self.handleError(record)

    def flush(self):
        self.stream.flush()

    def flushBufferTo(self, target):
        for record in self.buffer:
            target.handle(record)
        self.buffer = []




More information about the Zodb-checkins mailing list