[Zodb-checkins] CVS: Zope/lib/python/zLOG - component.xml:1.7.2.1 datatypes.py:1.10.2.1 factory.py:1.3.2.1 EventLogger.py:1.1.2.7 __init__.py:1.8.4.6
Fred L. Drake, Jr.
fred@zope.com
Thu, 23 Jan 2003 17:05:16 -0500
Update of /cvs-repository/Zope/lib/python/zLOG
In directory cvs.zope.org:/tmp/cvs-serv708
Modified Files:
Tag: chrism-install-branch
EventLogger.py __init__.py
Added Files:
Tag: chrism-install-branch
component.xml datatypes.py factory.py
Log Message:
Merge from the zLOG trunk.
=== Added File Zope/lib/python/zLOG/component.xml ===
<component prefix="zLOG.datatypes">
<abstracttype name="loghandler"/>
<sectiontype name="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=".logging_level"/>
</sectiontype>
<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=".SyslogHandlerFactory"
implements="loghandler" extends="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="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=".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"/>
<key name="format" default="%(asctime)s %(message)s"
datatype=".log_format"/>
</sectiontype>
<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"/>
<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>
<sectiontype name="eventlog" datatype=".EventLogFactory">
<key name="level" datatype=".logging_level" default="info"/>
<multisection type="loghandler" attribute="handlers" name="*"/>
</sectiontype>
</component>
=== Added File Zope/lib/python/zLOG/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."""
import sys
from zLOG.factory import Factory
# log-related datatypes
_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
_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
class FileHandlerFactory(HandlerFactory):
def create_loghandler(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,
"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 zLOG.LogHandlers import SysLogHandler
return SysLogHandler(self.section.address.address,
self.section.facility)
class Win32EventLogFactory(HandlerFactory):
def create_loghandler(self):
from zLOG.LogHandlers import Win32EventLogHandler
return 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 zLOG.LogHandlers import HTTPHandler
host, selector = self.section.url
return HTTPHandler(host, selector, self.section.method)
class SMTPHandlerFactory(HandlerFactory):
def create_loghandler(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)
class EventLogFactory(Factory):
"""
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.
"""
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("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
=== Added File Zope/lib/python/zLOG/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()")
=== Zope/lib/python/zLOG/EventLogger.py 1.1.2.6 => 1.1.2.7 ===
--- Zope/lib/python/zLOG/EventLogger.py:1.1.2.6 Fri Jan 3 01:47:00 2003
+++ Zope/lib/python/zLOG/EventLogger.py Thu Jan 23 17:04:42 2003
@@ -29,6 +29,12 @@
from LogHandlers import FileHandler, NullHandler, SysLogHandler
from logging import StreamHandler, Formatter
+# Custom logging levels
+CUSTOM_BLATHER = 15 # Mapping for zLOG.BLATHER
+CUSTOM_TRACE = 5 # Mapping for zLOG.TRACE
+logging.addLevelName("BLATHER", CUSTOM_BLATHER)
+logging.addLevelName("TRACE", CUSTOM_TRACE)
+
class EventLogger(BaseLogger):
logger = logging.getLogger('event')
log_format = '%(sev)s %(subsys)s %(summary)s%(detail)s'
@@ -85,23 +91,30 @@
zLOG severity PEP282 severity
------------- ---------------
- PANIC (300) critical (50)
- ERROR (200), PROBLEM (100) error (40)
- INFO (0) warn (30)
- BLATHER (-100) info (20)
- DEBUG (-200), TRACE (-300) debug (10)
+ PANIC (300) FATAL, CRITICAL (50)
+ ERROR (200) ERROR (40)
+ WARNING, PROBLEM (100) WARN (30)
+ INFO (0) INFO (20)
+ BLATHER (-100) BLATHER (15) [*]
+ DEBUG (-200) DEBUG (10)
+ TRACE (-300) TRACE (5) [*]
+
+ [*] BLATHER and TRACE are custom logging levels.
"""
sev = zlog_severity
if sev >= 300:
- return logging.CRITICAL
- if sev >= 100:
+ return logging.FATAL
+ if sev >= 200:
return logging.ERROR
- if sev >= 0:
+ if sev >= 100:
return logging.WARN
- if sev >= -100:
+ if sev >= 0:
return logging.INFO
- else:
+ if sev >= -100:
+ return CUSTOM_BLATHER
+ if sev >= -200:
return logging.DEBUG
+ return CUSTOM_TRACE
def log_time():
"""Return a simple time string without spaces suitable for logging."""
@@ -156,7 +169,8 @@
def initialize_from_environment():
""" Reinitialize the event logger from the environment """
# clear the current handlers from the event logger
- event_logger.logger.handlers = []
+ for h in event_logger.logger.handlers[:]:
+ event_logger.logger.removeHandler(h)
handlers = []
=== Zope/lib/python/zLOG/__init__.py 1.8.4.5 => 1.8.4.6 ===
--- Zope/lib/python/zLOG/__init__.py:1.8.4.5 Fri Jan 3 01:47:00 2003
+++ Zope/lib/python/zLOG/__init__.py Thu Jan 23 17:04:42 2003
@@ -25,7 +25,8 @@
programs will replace this method with a method more suited to their needs.
The module provides a register_subsystem method that does nothing, but
-provides a hook that logging management systems could use to collect information about subsystems being used.
+provides a hook that logging management systems could use to collect
+information about subsystems being used.
The module defines several standard severities:
@@ -68,10 +69,6 @@
traceback. If provided, then a summary of the error
is added to the detail.
-The callable object can provide a reinitialize method that may be
-called with no arguments to reopen the log files (if any) as part of a
-log-rotation facility.
-
There is a default event logging facility that:
- swallows logging information by default,
@@ -105,10 +102,26 @@
# Flag indicating whether LOG() should call initialize()
_call_initialize = 1
+# Function called to (re-)initialize the logger we're using
+_initializer = initialize_from_environment
+
def initialize():
global _call_initialize
_call_initialize = 0
- initialize_from_environment()
+ _initializer()
+
+def set_initializer(func):
+ """Set the function used to re-initialize the logs.
+
+ This should be called when initialize_from_environment() is not
+ appropiate.
+
+ This does not ensure that the new function gets called; the caller
+ should do that separately.
+ """
+ global _initializer
+ _initializer = func
+
def LOG(subsystem, severity, summary, detail='', error=None, reraise=None):
"""Log some information