[Patches] [ python-Patches-1412054 ] More easily extensible logging module
SourceForge.net
noreply at sourceforge.net
Sun Jan 22 14:50:27 CET 2006
Patches item #1412054, was opened at 2006-01-22 13:47
Message generated for change (Settings changed) made by dvarrazzo
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: Vinay Sajip (vsajip)
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