[PEAK] Logging changes

Phillip J. Eby pje at telecommunity.com
Thu Dec 11 19:44:07 EST 2003


As you may have already seen, the 'logging.logger:' URL scheme is being 
deprecated in favor of just plain 'logger:'.  The old name was from when I 
expected this to directly tie into the PEP 282 'logging' package.

I'd also like to deprecate the 'logs' module for direct usage, and get rid 
of the API calls it now has available like 'addLevelName()'.  These APIs 
were added in symmetry with the PEP 282 logging package, but I think this 
was the wrong thing to do, as it creates a mutable singleton with all of 
the attendant problems thereof.

So here's what I want to do instead.  I'm creating a new interface, 
ILoggingService, whose methods will be 'getLogger(name="")', 
'getLevelFor(ob,default=NOT_GIVEN)' and 
'getLevelName(lvl,default=NOT_GIVEN)'.  (The interface will also extend 
ILogger, with the methods all being delegated to the service's "root logger".)

The idea here is that ILoggingService will be used in place of the 'logs' 
module singleton.  There will be a default factory in peak.ini that will 
create a DefaultLoggingService, which is where the existing 'logs' API 
functions will move to.  Rather than having an 'addLevelName()' method, the 
DefaultLoggingService will get its levels from a configuration property or 
properties.

The 'logger:' URL will be changed to find loggers by first getting an 
ILoggingService, and then calling its 'getLogger()' method.  The 
DefaultLoggingService will then delegate this to the 'peak.logs' property 
namespace, so that existing configuration files will have the same semantics.

These changes should make it easier for someone to create a 
PEP282LoggingService class that wraps the Python 2.3 'logging' package and 
loads a configuration into it.  The 'logging' package, alas, is both a 
singleton *and* requires imperative configuration rather than declarative 
configuration.  However, it should be possible to kludge it in to PEAK in 
the same way we did for Twisted's singleton-and-imperative "reactor" 
system.  This would then permit access to PEP 282's wider range of 
implemented formatters, handlers, etc., including syslog, rotating logs, 
etc.  It would also be possible to create alternative ILoggingService 
implementations that used e.g. ZConfig or other mechanisms for configuration.

In addition, making these changes would make it possible for logger objects 
to be shared.  Right now, every object that references some logger 
'foo.bar' gets its own instance of that logger.  I'm not sure if this is 
good or bad yet, though.  The good thing about multiple logger instances is 
that they can bind to their immediate context and pick up additional 
configuration capabilities.  The bad thing is that it's potentially 
expensive in both CPU and memory usage to create so many loggers.

Last, but not least, the net result of these changes would be that the 
'logs' module would not need to be part of peak.api any more, since that 
would no longer be the place to get log levels from.  (The PEP 282-defined 
log levels will still be available as constants from peak.running.logs, so 
that logger classes can efficiently compare their filtering level against 
the constants in their 'info()', 'warning()', etc. methods.)

Does anybody have any objections to any of this?  Any thoughts about the 
benefits of having lots of logger instances per logger name (status quo) 
versus having only one instance per logger name per logging service?  Thanks.





More information about the PEAK mailing list