[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