[Patches] [ python-Patches-1412054 ] More easily extensible logging module

SourceForge.net noreply at sourceforge.net
Sun Jan 22 14:47:54 CET 2006


Patches item #1412054, was opened at 2006-01-22 13:47
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1412054&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Library (Lib)
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Daniele Varrazzo (dvarrazzo)
Assigned to: Nobody/Anonymous (nobody)
Summary: More easily extensible logging module

Initial Comment:
The Python logging.Logger class is supposed being
extensible by overriding the makeRecord() method. 

This is not completely true because the public logging
method (log(), debug(), info()...) call the less public
_log(), which in turn call makeRecord(). While the
public methods have a signature such:

    def info(self, msg, *args, **kwargs):
        ...
        apply(self._log, (INFO, msg, args), kwargs)

thus leaving room for expansion, the _log() method is
not so much flexible:

    def _log(self, level, msg, args, exc_info=None):
        # ...interesting stuff here...
        record = self.makeRecord(self.name, level, fn,
lno, msg, args, exc_info)
        self.handle(record)

The makeRecord signature is:

    def makeRecord(self, name, level, fn, lno, msg,
args, exc_info):

So if anybody wants to add a keyword to makeRecord, he
also needs to re-implement the "interesting stuff" in
the supposed private _log (finding the source row,
reading the stack trace...).

The attached patch should leave the _log behavior
unchanged but all unknown keyword arguments are passed
to makeRecord.

If a wrong parameter is passed to any public method,
the logger as before raises an exception, which is
raised on the makeRecord() call instead of _log()'s.

With the patch on, use case for an user that want to
log extra keywords is:

    import logging
    
    # Logger customization

    class MyLogRecord(logging.LogRecord):
        """Add a foo to a log record."""
        def __init__(self, name, level, pathname, 
                     lineno, msg, args, exc_info, foo):
            logging.LogRecord.__init__(self, name,
level, pathname,
                                       lineno, msg,
args, exc_info)
            self.foo = foo
    
    class MyLogger(logging.Logger):
        """Can log foos too."""
        def makeRecord(self, name, level, fn, 
                       lno, msg, args, exc_info, foo):
            return MyLogRecord(name, level, fn, 
                               lno, msg, args,
exc_info, foo)
    
    class MyHandler(logging.Handler):
        """Can handle foo records."""
        def emit(self, record):
            if isinstance(record, MyLogRecord):
                print self.format(record), record.foo
    
    # Logger configuration

    logging.setLoggerClass(MyLogger)
    logger = logging.getLogger('test')
    logger.setLevel(logging.INFO)
    
    hndl = MyHandler(level=logging.INFO)
    hndl.setFormatter(
        logging.Formatter("%(message)s at line
#%(lineno)d"))
    logger.addHandler(hndl)
    
    # Logger usage

    logger.info("Message", foo='pippo')
    # prints something like "Message at line #40 pippo"


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1412054&group_id=5470


More information about the Patches mailing list