1############################################################################## 2# 3# Copyright (c) 2003 Zope Foundation and Contributors. 4# All Rights Reserved. 5# 6# This software is subject to the provisions of the Zope Public License, 7# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. 8# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED 9# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 10# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS 11# FOR A PARTICULAR PURPOSE. 12# 13############################################################################## 14"""ZConfig factory datatypes for loggers.""" 15 16from ZConfig.components.logger.factory import Factory 17 18 19class LoggerFactoryBase(Factory): 20 """Base class for logger factories. 21 22 Factory used to create loggers while delaying actual logger 23 instance construction. We need to do this because we may want to 24 reference a logger before actually instantiating it (for example, 25 to allow the app time to set an effective user). An instance of 26 this wrapper is a callable which, when called, returns a logger 27 object. 28 """ 29 30 def __init__(self, section): 31 Factory.__init__(self) 32 self.level = section.level 33 self.handler_factories = section.handlers 34 35 def create(self): 36 # set the logger up 37 import logging 38 logger = logging.getLogger(self.name) 39 logger.setLevel(self.level) 40 if self.handler_factories: 41 for handler_factory in self.handler_factories: 42 handler = handler_factory() 43 logger.addHandler(handler) 44 else: 45 from ZConfig.components.logger import loghandler 46 logger.addHandler(loghandler.NullHandler()) 47 return logger 48 49 def startup(self): 50 # make sure we've instantiated the logger 51 self() 52 53 def getLowestHandlerLevel(self): 54 """Return the lowest log level provided by any configured handler. 55 56 If all handlers and the logger itself have level==NOTSET, this 57 returns NOTSET. 58 """ 59 import logging 60 lowest = self.level 61 for factory in self.handler_factories: 62 level = factory.getLevel() 63 if level != logging.NOTSET: 64 if lowest == logging.NOTSET: 65 lowest = level 66 else: 67 lowest = min(lowest, level) 68 return lowest 69 70 def reopen(self): 71 """Re-open any handlers for which this is a meaningful operation. 72 73 This only works on handlers on the logger provided by this 74 factory directly; handlers for child loggers are not affected. 75 (This can be considered a bug, but is sufficient at the 76 moment.) 77 """ 78 logger = self() 79 for handler in logger.handlers: 80 reopen = getattr(handler, "reopen", None) 81 if reopen is not None and callable(reopen): 82 reopen() 83 84 85class EventLogFactory(LoggerFactoryBase): 86 """Logger factory that returns the root logger.""" 87 88 name = None 89 90 91class LoggerFactory(LoggerFactoryBase): 92 """Logger factory that returns the named logger.""" 93 94 def __init__(self, section): 95 LoggerFactoryBase.__init__(self, section) 96 self.name = section.name 97 self.propagate = section.propagate 98 99 def create(self): 100 logger = LoggerFactoryBase.create(self) 101 logger.propagate = self.propagate 102 return logger 103