[Zodb-checkins] CVS: Zope/lib/python/zLOG - BaseLogger.py:1.2 EventLogger.py:1.2 LogHandlers.py:1.2 __init__.py:1.13 MinimalLogger.py:NONE
Chris McDonough
chrism@zope.com
Sun, 24 Nov 2002 00:24:43 -0500
Update of /cvs-repository/Zope/lib/python/zLOG
In directory cvs.zope.org:/tmp/cvs-serv18617
Modified Files:
__init__.py
Added Files:
BaseLogger.py EventLogger.py LogHandlers.py
Removed Files:
MinimalLogger.py
Log Message:
Use PEP282-based logger instead of homegrown.
=== Zope/lib/python/zLOG/BaseLogger.py 1.1 => 1.2 ===
--- /dev/null Sun Nov 24 00:24:43 2002
+++ Zope/lib/python/zLOG/BaseLogger.py Sun Nov 24 00:24:43 2002
@@ -0,0 +1,24 @@
+##############################################################################
+#
+# 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()
+
=== Zope/lib/python/zLOG/EventLogger.py 1.1 => 1.2 ===
--- /dev/null Sun Nov 24 00:24:43 2002
+++ Zope/lib/python/zLOG/EventLogger.py Sun Nov 24 00:24:43 2002
@@ -0,0 +1,191 @@
+##############################################################################
+#
+# 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, sys, 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)
+
+EventLogger = EventLogger()
+
+log_write = EventLogger.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
+ EventLogger.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)
+ EventLogger.logger.setLevel(severity)
+
+ for handler in handlers:
+ EventLogger.logger.addHandler(handler)
+
=== Zope/lib/python/zLOG/LogHandlers.py 1.1 => 1.2 ===
--- /dev/null Sun Nov 24 00:24:43 2002
+++ Zope/lib/python/zLOG/LogHandlers.py Sun Nov 24 00:24:43 2002
@@ -0,0 +1,78 @@
+##############################################################################
+#
+# 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 """
+
+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 = []
+
+
+
+
+
=== Zope/lib/python/zLOG/__init__.py 1.12 => 1.13 ===
--- Zope/lib/python/zLOG/__init__.py:1.12 Fri Nov 22 13:17:39 2002
+++ Zope/lib/python/zLOG/__init__.py Sun Nov 24 00:24:43 2002
@@ -88,8 +88,8 @@
"""
__version__='$Revision$'[11:-2]
-from MinimalLogger import log_write, log_time, severity_string, \
- _set_log_dest, initialize
+from EventLogger import log_write, log_time, severity_string, \
+ initialize_from_environment as initialize
from traceback import format_exception
# Standard severities
=== Removed File Zope/lib/python/zLOG/MinimalLogger.py ===