This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: feature requests for logging lib
Type: enhancement Stage:
Components: Library (Lib) Versions:
process
Status: closed Resolution: duplicate
Dependencies: Superseder:
Assigned To: Nosy List: blaize, georg.brandl
Priority: normal Keywords:

Created on 2006-04-22 12:02 by blaize, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (2)
msg54789 - (view) Author: blaize rhodes (blaize) Date: 2006-04-22 12:02

The logger module interface is a bit broken, I reckon.
 My problems specifically are:
 
	i) It's hard to get access to the LogRecord classes
for customization.
	ii) the semantics of the debug, log, info, etc calls
is a bit strange/confusing...



Here are my proposed fixes:

a)  Add a method 
   Logger.setLogRecordClass( myLogRecordSubClass )

which sets the class that is instantiated in the
makeRecord() fn/method (yes there are two of them).

This would make customizing the LogRecord easier... 
Otherwise (I believe) in order to subclass the
LogRecord you also have to overload the Logger and
possibly the root makeRecord() function as well?  This
bloke's writen up his approach to this (it's doable but
not as nice as it should be).
 
http://qix.it/~ludoo/archive/2004/05/python_logging_customization.html

Another problem is that LogRecords are instantiated in
Logger._log so it's difficult to customize __init__
behaviour for the LogRecord (and I argue that this is a
useful thing)..  

b) A second problem is that the semantics of the log,
info, debug, etc fns is a bit broken.  Currently the
defn looks like this:

  def debug(self, msg, *args, **kwargs):

this suggests to me that a call like this is OK...

  logger.debug("here we go %(foo)s", foo = 'bar')

but it's not.  This is discussed further here...

http://groups.google.com.au/group/comp.lang.python/browse_thread/thread/322919fcac0113ec/98ceaf6fc0c56881?lnk=st&q=python+logging+keywords&rnum=1#98ceaf6fc0c56881

Instead kwargs are used for customizing the behaviour
of the debug method (e.g. exc_info, and extra).  This
seems i) a bit incongrous with its definition and
therefore confusing, and ii) a bit of a hack (it's not
completely insane though when you think about what's
happening under the hood).  Instead I propose using a
couple of calls along the lines of printf/fprintf.  In
my world we'd have a simple printf-style function... 

  def debug(self, msg, *args):  

and a more complex, more easily customizable
fprintf-style one

  def x_debug(self, log_record, msg, *args):  

In these calls *args is a valid argument for the string
formatting operator %, either a tuple of the right
length or a dictionary.  Any customization of the
behaviour of the system can be done (using keyword args
if you wish) in the log_record initializer (an example
will follow).

(Having said that perhaps we can check whether the
first arg to the new simple debug() is a logrecord and
if it is call the (hidden) extended version - that's
more pythonic I imagine)


c) This is not so much a feature request but a
motivating mode of operation that I'd like to be able
to use...

Currently you can set up log filters.  What you can
filter is largely based on what information appears in
the log record.  It'd be nice to filter messages based
on metadata  that you add at log time (i.e. in the
logger.debug(...) method).  Currently it's quite
painfull to set this up.  This is because we can't
customize the initialization of the log_record.  The
call structure in ii) above allows us to setup nice
filtering mechanisms
eg..

class GUIFilter:
   "A filter that only lets messges with gui tags
through."""
	def filter(self, log_record):
	    return hasattr(log_record, 'gui')

# set up a log, and a handler...
log = logging.getLogger(..)
file_handler = FileHandler(..)
log.addHandler(file_handler)
gui_msg_bar_handler = StreamHandler(..)
log.addHandler(gui_msg_bar_handler)
gui_msg_bar_handler.addFilter(GUIFilter())

# msg only goes to the file_handler
log.debug("here we go %s", "here's an arg")  

# msg goes to the file_handler and to the gui_handler.
log.x_debug(LogRecord(gui=True), "what you just tried
to do didn't work %s", "fool")


Change a) could be made with no backward compatability
problems (I can see), change b) could be made without
probs if you didn't overload the existing logging
methods with the new ones, and then deprecate the
existing ones  (though what you'd call the new fns I
don't know).

That said I quite like the logger lib and I use it. 
It's a lot better than anything I would have thought up.


cheers
    blaize

msg54790 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-04-27 12:59
Logged In: YES 
user_id=849994

Duplicate of #1474577.
History
Date User Action Args
2022-04-11 14:56:17adminsetgithub: 43261
2006-04-22 12:02:18blaizecreate