Commit 9764267f authored by Fred Drake's avatar Fred Drake

Remove all logging configuration from zLOG; the only thing zLOG provides now

is an API shim to the logging module.  No more competing initializations!
parent a45f4129
......@@ -20,13 +20,8 @@ This uses Vinay Sajip's PEP 282 logging module.
__version__='$Revision$'[11:-2]
import logging
import os
import time
from BaseLogger import BaseLogger
from ZConfig.components.logger import loghandler
from logging import StreamHandler, Formatter
# Custom logging levels
CUSTOM_BLATHER = 15 # Mapping for zLOG.BLATHER
CUSTOM_TRACE = 5 # Mapping for zLOG.TRACE
......@@ -102,94 +97,3 @@ 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():
"""Return the severity setting based on the environment.
The value returned is a zLOG severity, not a logging package severity.
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():
"""Return the path of the log file to write to based on the
environment.
EVENT_LOG_FILE is the preferred envvar, but we accept
STUPID_LOG_FILE also.
"""
eget = os.environ.get
return eget('EVENT_LOG_FILE') or eget('STUPID_LOG_FILE')
formatters = {
'file': Formatter(fmt=('------\n%(asctime)s %(levelname)s %(name)s'
' %(message)s'),
datefmt='%Y-%m-%dT%H:%M:%S'),
'syslog': Formatter(fmt='%(levelname)s %(name)s %(message)s'),
}
def initialize_from_environment():
""" Reinitialize the event logger from the environment """
# clear the current handlers from the event logger
logger = logging.getLogger()
for h in logger.handlers[:]:
logger.removeHandler(h)
handlers = []
# set up syslog handler if necessary
facility, syslogdest = get_env_syslog_info()
if syslogdest:
handler = loghandler.SysLogHandler(syslogdest, facility)
handler.setFormatter(formatters['syslog'])
handlers.append(handler)
# set up file handler if necessary
filedest = get_env_file_info()
if filedest:
handler = loghandler.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(loghandler.NullHandler())
severity = get_env_severity_info()
severity = zlog_to_pep282_severity(severity)
logger.setLevel(severity)
for handler in handlers:
logger.addHandler(handler)
......@@ -83,10 +83,7 @@ There is a default event logging facility that:
can be overridden with the environment variable EVENT_LOG_SEVERITY
"""
__version__='$Revision: 1.18 $'[11:-2]
from EventLogger import log_write, log_time, severity_string, \
initialize_from_environment
from EventLogger import log_write, log_time, severity_string
from traceback import format_exception
# Standard severities
......@@ -99,16 +96,9 @@ WARNING = 100
ERROR = 200
PANIC = 300
# 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
_initializer()
pass
def set_initializer(func):
"""Set the function used to re-initialize the logs.
......@@ -119,8 +109,7 @@ def set_initializer(func):
This does not ensure that the new function gets called; the caller
should do that separately.
"""
global _initializer
_initializer = func
pass
def LOG(subsystem, severity, summary, detail='', error=None, reraise=None):
......@@ -148,13 +137,11 @@ def LOG(subsystem, severity, summary, detail='', error=None, reraise=None):
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]
_subsystems=[]
_subsystems = []
def register_subsystem(subsystem):
"""Register a subsystem name
......
<component prefix="zLOG.datatypes">
<import package="ZConfig.components.logger" file="abstract.xml"/>
<import package="ZConfig.components.logger" file="handlers.xml"/>
<sectiontype name="eventlog"
datatype=".EventLogFactory"
implements="ZConfig.logger.log">
<key name="level"
datatype="ZConfig.components.logger.datatypes.logging_level"
default="info"/>
<multisection name="*"
type="ZConfig.logger.handler"
attribute="handlers"
/>
</sectiontype>
</component>
##############################################################################
#
# 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 zLOG
from zLOG import EventLogger
from ZConfig.components.logger import logger
class EventLogFactory(logger.EventLogFactory):
"""Factory used to create a logger to use with zLOG.
This adds the getLowestHandlerLevel() method to make it suitable
for Zope and replaces the startup() method to ensure zLOG is
properly initialized.
"""
def getLowestHandlerLevel(self):
""" Return the lowest log level provided by any of our handlers
(used by Zope startup logger code to decide what to send
to stderr during startup) """
lowest = self.level
for factory in self.handler_factories:
handler_level = factory.getLevel()
if handler_level < lowest:
lowest = factory.getLevel()
return lowest
def initialize(self):
logger = self()
for handler in logger.handlers:
if hasattr(handler, "reopen"):
handler.reopen()
def startup(self):
zLOG.set_initializer(self.initialize)
zLOG.initialize()
......@@ -162,6 +162,7 @@ class EventLogTest(StupidLogTest):
prefix = 'EVENT'
def test_suite():
return unittest.TestSuite()
suite = unittest.makeSuite(StupidLogTest, 'check')
suite.addTest(unittest.makeSuite(EventLogTest, 'check'))
return suite
......
##############################################################################
#
# 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.
#
##############################################################################
"""Tests for zLOG configuration via ZConfig."""
import cStringIO as StringIO
import logging
import unittest
import ZConfig
from ZConfig.components.logger import loghandler
class TestzLOGConfig(unittest.TestCase):
# XXX This tries to save and restore the state of logging around
# the test. Somewhat surgical; there may be a better way.
def setUp(self):
self._old_logger = logging.getLogger()
self._old_level = self._old_logger.level
self._old_handlers = self._old_logger.handlers[:]
self._old_logger.handlers[:] = [loghandler.NullHandler()]
def tearDown(self):
for h in self._old_logger.handlers:
self._old_logger.removeHandler(h)
for h in self._old_handlers:
self._old_logger.addHandler(h)
self._old_logger.setLevel(self._old_level)
_schema = None
_schematext = """
<schema>
<import package='zLOG'/>
<section type='eventlog' name='*' attribute='eventlog'/>
</schema>
"""
def get_schema(self):
if self._schema is None:
sio = StringIO.StringIO(self._schematext)
self.__class__._schema = ZConfig.loadSchemaFile(sio)
return self._schema
def get_config(self, text):
conf, handler = ZConfig.loadConfigFile(self.get_schema(),
StringIO.StringIO(text))
self.assert_(not handler)
return conf
def test_config_without_logger(self):
conf = self.get_config("")
self.assert_(conf.eventlog is None)
def test_config_without_handlers(self):
logger = self.check_simple_logger("<eventlog/>")
# Make sure there's a NullHandler, since a warning gets
# printed if there are no handlers:
self.assertEqual(len(logger.handlers), 1)
self.assert_(isinstance(logger.handlers[0],
loghandler.NullHandler))
def check_simple_logger(self, text, level=logging.INFO):
conf = self.get_config(text)
self.assert_(conf.eventlog is not None)
self.assertEqual(conf.eventlog.level, level)
logger = conf.eventlog()
self.assert_(isinstance(logger, logging.Logger))
self.assertEqual(len(logger.handlers), 1)
return logger
def test_suite():
return unittest.makeSuite(TestzLOGConfig)
if __name__ == '__main__':
unittest.main(defaultTest="test_suite")
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment