[PEAK] peak.running.logging

Phillip J. Eby pje at telecommunity.com
Thu Nov 27 16:10:33 EST 2003


At 03:27 PM 11/27/03 -0500, Victor Ng wrote:

>I'm having a bit of a tough time figuring out what's going on with the 
>peak.running.logs though.  How do I go about customizing the log messages?
>
>In particular when I do something like this:
>
>log        = binding.Obtain('logging.logger:storage.AddContact')
>
>Where does the "storage.AddContact" go?  In fact, what is it used for?
>I was under the impression that it's a logical name for a logger and it 
>should show up in the log messages.

That might be a good idea.  For now, PEAK's default log system looks a lot 
like that of AppUtils, a utility library that Ty wrote.  I'll probably work 
up a more pluggable system at some point, once more PEAK-based logs are 
part of our day-to-day work.  (This might not take all that long, though.)


>I've also tried subclassing the peak.running.logs.LogFile class and 
>changing the publish method, but I"m not sure how to get peak.logs to use 
>my custom logfile logger.  Here's what I've put in my initial 
>configuration (based on the bulletins example).
>
>[peak.logs]
>* = sextant.logs.SextantLogFile(filename='/usr/local/log/sextant.log', 
>level=logs.DEBUG)
>
>The above throws an error saying "sextant" is undefined - how do I declare 
>an import using the config files?  Or am I running in completely the wrong 
>direction here?  It feels like I'm doing something horribly wrong.


[peak.logs]
* = importString('sextant.logs.SextantLogFile')(
      filename='/usr/local/log/sextant.log'
  )

Of course, this is more awkward than also defining your own URL scheme or 
using a naming.Reference.  If your class implemented IObjectFactory, you 
could do this:

[peak.logs]
* = naming.Reference(
      'sextant.logs.SextantLogFile',
      ['file://usr/local/log/sextant.log']
   )

Actually, I just checked, and LogFile already implements IObjectFactory, so 
you should be able to do this right now.


>My ultimate goal would be to have a logger that takes in a couple 
>arguments so that I can get event records with event ID numbers in the 
>log.  Something like this:
>
>2003-11-27 14:20:51,dhcp139,storage.AddContact,555,777,"Creating 
>sqlite:///tmp/sextant.db using DDL from 
>/Users/victorng/dev/sextant/src/sextant/sqlite-ddl.sql"
>
>where 555 and 777 are status code passed in when call the logging system.

Keep in mind that you can implement your own Event classes, and pass them 
to 'self.log.publish()'.  The default loggers simply call str() on the 
Event in order to format it, so the easiest way to customize the format for 
custom loggers is to redefine the 'str()' method.

Also, if you define your loggers to use a custom Event class, then you can 
also supply keyword arguments to the standard debug()/warning()/info()/etc. 
methods.

Last, but not least, if you prefer to use the PEP 282 logging system with 
custom filters, formatters, etc. you can map the peak.logs property 
namespace over to the PEP 282 logging package fairly easily with a * rule, 
e.g.:

[peak.logs]
* = importString('logging.getLogger')(ruleSuffix)

IIRC, this would return you the PEP 282 logger corresponding to the rule.


Now that you've brought the subject to my attention, I can see some areas 
where the current logging system could be spruced up a bit.  For example, 
the EventClass used by loggers should be controlled by a property or 
interface lookup.  (Probably there should be an ILogEventFactory interface, 
with the current EventClass registered as the default supplier.)

Second, the Event class itself should use a standard PEAK constructor 
signature, and use configuration properties for characteristics like its 
'ident' string.  (Loggers should offer local copies of these properties for 
faster lookup by each new Event, or else supply them as keyword 
arguments.)  And finally, the formatting mechanism should probably 
separated from the event-tracking and output mechanisms.





More information about the PEAK mailing list