[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