[Zodb-checkins] CVS: ZODB3/zLOG - BaseLogger.py:1.2.14.1 EventLogger.py:1.4.2.1 LogHandlers.py:1.3.6.1 __init__.py:1.8.40.2 FormatException.py:NONE MinimalLogger.py:NONE
Fred L. Drake, Jr.
fred@zope.com
Tue, 17 Dec 2002 14:32:41 -0500
Update of /cvs-repository/ZODB3/zLOG
In directory cvs.zope.org:/tmp/cvs-serv6789
Modified Files:
Tag: ZODB3-fast-restart-branch
__init__.py
Added Files:
Tag: ZODB3-fast-restart-branch
BaseLogger.py EventLogger.py LogHandlers.py
Removed Files:
Tag: ZODB3-fast-restart-branch
FormatException.py MinimalLogger.py
Log Message:
Backport the logging package integration from the Zope 2 trunk.
=== Added File ZODB3/zLOG/BaseLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 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
#
##############################################################################
"""
An abstract logger meant to provide features to the access logger,
the event logger, and the debug logger.
"""
class BaseLogger:
def reopen(self):
for handler in self.logger.handlers:
if hasattr(handler, 'reopen') and callable(handler.reopen):
handler.reopen()
=== Added File ZODB3/zLOG/EventLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 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
#
##############################################################################
"""
A logging module which handles event messages.
This uses Vinay Sajip's PEP 282 logging module.
"""
__version__='$Revision$'[11:-2]
import os, time
try:
import textwrap
except ImportError:
textwrap = None
import logging
from BaseLogger import BaseLogger
from LogHandlers import FileHandler, NullHandler, SysLogHandler
from logging import StreamHandler, Formatter
class EventLogger(BaseLogger):
logger = logging.getLogger('event')
logger.addHandler(NullHandler())
log_format = '%(sev)s %(subsys)s %(summary)s%(detail)s'
def log(self, subsystem, severity, summary, detail, error):
if error:
kw = {'exc_info':1}
else:
kw = {}
if detail:
detail = '\n' + detail
else:
detail = ''
msg = self.log_format % {
'sev' : severity_string(severity),
'subsys' : subsystem,
'summary': summary,
'detail' : detail,
}
if textwrap and len(msg) > 80:
msg = '\n'.join(textwrap.wrap(
msg, width=79, subsequent_indent=" "*20,
break_long_words=0))
severity = zlog_to_pep282_severity(severity)
self.logger.log(severity, msg, **kw)
event_logger = EventLogger()
log_write = event_logger.log
def severity_string(severity, mapping={
-300: 'TRACE',
-200: 'DEBUG',
-100: 'BLATHER',
0: 'INFO',
100: 'PROBLEM',
200: 'ERROR',
300: 'PANIC',
}):
"""Convert a severity code to a string."""
s = mapping.get(int(severity), '')
return "%s(%s)" % (s, severity)
def zlog_to_pep282_severity(zlog_severity):
"""
We map zLOG severities to PEP282 severities here.
This is how they are mapped:
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)
"""
sev = zlog_severity
if sev >= 300:
return logging.CRITICAL
if sev >= 100:
return logging.ERROR
if sev >= 0:
return logging.WARN
if sev >= -100:
return logging.INFO
else:
return logging.DEBUG
def log_time():
"""Return a simple time string without spaces suitable for logging."""
return ("%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d"
% time.localtime()[:6])
def get_env_severity_info():
# EVENT_LOG_SEVERITY is the preferred envvar, but we accept
# STUPID_LOG_SEVERITY also
eget = os.environ.get
severity = eget('EVENT_LOG_SEVERITY') or eget('STUPID_LOG_SEVERITY')
if severity:
severity = int(severity)
else:
severity = 0 # INFO
return severity
def get_env_syslog_info():
eget = os.environ.get
addr = None
port = None
path = eget('ZSYSLOG')
facility = eget('ZSYSLOG_FACILITY', 'user')
server = eget('ZSYSLOG_SERVER')
if server:
addr, port = server.split(':')
port = int(port)
if addr:
return (facility, (addr, port))
else:
return (facility, path)
def get_env_file_info():
eget = os.environ.get
# EVENT_LOG_FILE is the preferred envvar, but we accept
# STUPID_LOG_FILE also
path = eget('EVENT_LOG_FILE')
if path is None:
path = eget('STUPID_LOG_FILE')
if path is None:
dest = None
else:
dest = path
return dest
formatters = {
'file': Formatter(fmt='------\n%(asctime)s %(message)s',
datefmt='%Y-%m-%dT%H:%M:%S'),
'syslog': Formatter(fmt='%(message)s'),
}
def initialize_from_environment():
""" Reinitialize the event logger from the environment """
# clear the current handlers from the event logger
event_logger.logger.handlers = []
handlers = []
# set up syslog handler if necessary
facility, syslogdest = get_env_syslog_info()
if syslogdest:
handler = SysLogHandler(syslogdest, facility)
handler.setFormatter(formatters['syslog'])
handlers.append(handler)
# set up file handler if necessary
filedest = get_env_file_info()
if filedest:
handler = FileHandler(filedest)
handler.setFormatter(formatters['file'])
handlers.append(handler)
elif filedest == '':
# if dest is an empty string, log to standard error
handler = StreamHandler()
handler.setFormatter(formatters['file'])
handlers.append(handler)
else:
# log to nowhere, but install a 'null' handler in order to
# prevent error messages from emanating due to a missing handler
handlers.append(NullHandler())
severity = get_env_severity_info()
severity = zlog_to_pep282_severity(severity)
event_logger.logger.setLevel(severity)
for handler in handlers:
event_logger.logger.addHandler(handler)
=== Added File ZODB3/zLOG/LogHandlers.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
class FileHandler(StreamHandler):
"""
A file handler which allows for reopening of logs in favor of the
'rollover' features of the standard PEP282 FileHandler.
"""
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):
"""
A null handler. 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()
def flush(self):
self.stream.flush()
def flushBufferTo(self, target):
for record in self.buffer:
target.handle(record)
self.buffer = []
=== ZODB3/zLOG/__init__.py 1.8.40.1 => 1.8.40.2 ===
--- ZODB3/zLOG/__init__.py:1.8.40.1 Tue Dec 17 11:26:43 2002
+++ ZODB3/zLOG/__init__.py Tue Dec 17 14:32:40 2002
@@ -8,7 +8,7 @@
# 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
+# FOR A PARTICULAR PURPOSE.
#
##############################################################################
@@ -47,7 +47,7 @@
PANIC=300 -- We're dead!
-Also, looging facilities will normally ignore negative severities.
+Also, logging facilities will normally ignore negative severities.
To plug in a log handler, simply replace the log_write function
with a callable object that takes 5 arguments:
@@ -89,9 +89,9 @@
"""
__version__='$Revision$'[11:-2]
-from MinimalLogger import log_write, log_time, severity_string, \
- _set_log_dest, initialize
-from FormatException import format_exception
+from EventLogger import log_write, log_time, severity_string, \
+ initialize_from_environment
+from traceback import format_exception
# Standard severities
TRACE = -300
@@ -103,6 +103,14 @@
ERROR = 200
PANIC = 300
+# Flag indicating whether LOG() should call initialize()
+_call_initialize = 1
+
+def initialize():
+ global _call_initialize
+ _call_initialize = 0
+ initialize_from_environment()
+
def LOG(subsystem, severity, summary, detail='', error=None, reraise=None):
"""Log some information
@@ -128,6 +136,8 @@
error is reraised.
"""
+ if _call_initialize:
+ initialize()
log_write(subsystem, severity, summary, detail, error)
if reraise and error:
raise error[0], error[1], error[2]
=== Removed File ZODB3/zLOG/FormatException.py ===
=== Removed File ZODB3/zLOG/MinimalLogger.py ===