[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