Unification of logging in Python's Standard Library

Matthew Barnes matthew at barnes.net
Tue Aug 19 20:55:44 EDT 2003


"A.M. Kuchling" <amk at amk.ca> wrote>:
> I suspect a PEP is required, because there are more issues here than just
> changing sys.stderr.write() to logging.info().  For example, what logger
> should modules use to log messages?  If they use the root logger, it will be
> difficult to discard messages from asyncore while keeping messages from the
> ZODB.  If they use a particular logger, how is this name chosen?  Is it
> dependent on the module name, so asyncore logs to 'asyncore' and so forth?
> What if my application has a logger named 'network', and I want it to go to
> 'network.asyncore', 'database.ZODB', etc.?
> 
> If the user specifies a logger, how is this done?  Does every public method
> have to grow an optional 'log' argument, or is there a module-level global
> setting, so you'd call
> asyncore.set_logger(logging.getLogger('network.asyncore'))?  
> 
> None of these options are very difficult to implement, but choosing which
> one will take some care; otherwise we'll be saddled with an inconvenient
> implementation that we'll be forever working around.


"John Roth" <newsgroups at jhrothjr.com> wrote:
> I'm going to agree with Andrew: write a PEP.
> 
> Unittest, as far as I know, doesn't have a logging system, and
> I, for one, don't want to see it burdened with a completely unnecessary
> logging system. I can't comment on the other examples in your
> list because I've never used them, but unittest is part of my standard
> project life, and I like it the way it is, thanks. Kent Beck and the
> other people involved in the xUnit development put a lot of thought
> into how it works, and AFKC, lack of logging isn't one of the problems.


Andrew raised some very good points, and a PEP probably is necessary. 
I did have some half baked ideas on how to go about this.

Generally speaking, the default logging output of each module that
uses 'logging' should be identical or as identical as possible to what
the module currently produces.  This would (hopefully) make the
transition nearly transparent to end-users.  Then we provide some
'hook' at either a module-level or (preferably) class-level for
replacing the default logger with a customized one.

Here's a few more module-specific thoughts:

asyncore.py
-----------
Add a 'logger' attribute to the 'dispatcher' class, which defaults to
a logger named 'asyncore' (i.e. the module's __name__) configured to
use a StreamHandler.  This would allow each instance of
asyncore.dispatcher to potentially have a unique logger.

BaseHTTPServer.py
-----------------
Add a 'logger' attribute to the 'BaseHTTPRequestHandler' class, which
defaults to a logger named 'BaseHTTPServer' (i.e. the module's
__name__) configured to use a StreamHandler and a Formatter that
produces the RFC931-style messages that are currently produced (note:
haven't looked into whether a logging.Formatter can do that).  This
would allow each instance of BaseHTTPServer.BaseHTTPRequestHandler to
potentially have a unique logger.

cgi.py
------
Not quite sure about what to do with this one; Andrew's questions pop
up here.  Perhaps provide a logger named 'cgi' (i.e. the module's
__name__) configured to use a StreamHandler.  The functions should use
a module-level 'logger' variable (initialized to the 'cgi' logger)
rather than hard-coding the logger name into the function bodies.  The
'logger' variable could then be assigned a different logger instance
and the functions would pick up on it.


I need to kill some more brain cells on the other modules in my list. 
I will say that unittest is what motivated me to suggest this in the
first place, since I'm working on a testing framework that is
attempting to take advantage of both the unittest *and* logging
modules.  Perhaps a new TestRunner class that uses logging
(LoggingTestRunner?) might coexist with the default TextTestRunner.

Matt




More information about the Python-list mailing list