fine grain logging cotrol
Eric S. Johansson
esj at harvee.org
Thu Mar 22 11:58:44 EDT 2007
Peter Otten wrote:
> Eric S. Johansson wrote:
>
>> I need to to be able to conditionally log based on the method the log
>> statement is in and one other factor like a log level. in order to do
>> so, I need to be able to automatically find out the name of the method
>> and its class but I haven't found out how to do that yet.
>>
>> for example,
>>
>> class catus(Felis):
>> def Siamese_cat( yowl, purr, demand_food):
>>
>> ...
>> log("state of litter box %s"% litter_box.smell, level = 1)
>>
>>
>> If the table of methods logged contains "catus.Siamese_cat", then I
>> would expect to see the output of the log statements in a log file. If
>> not then I wouldn't see anything in the log.
>>
>> Has somebody done this already? Is it even possible to do without
>> manually adding the class and method information for every log statement?
>>
>> a related question is using signals for reloading configurations etc. I
>> have to find any good examples of how to use signals to cause a
>> long-running process to reload external data. Any good pointers?
>
> Instead of rolling your own, use the logging package which can handle
> everything but the class info out of the box (levels are spelt as method
> names info(), warn() etc.).
I was planning on using logging. I've been using syslog for too long
>
> import logging
>
> class LoggedType(type):
> def __new__(mcl, name, bases, classdict):
> classdict["logger"] = logging.getLogger(name)
> return type.__new__(mcl, name, bases, classdict)
__new__ is new to me. took a look at
http://www.python.org/download/releases/2.2.3/descrintro/#__new__ which
give me some clue but not enough. what I get is that in call
initialization, you add an entry to the class dict (adds new method??).
I see that name, bases, or classdict are part of the normal class
construction process and refer to the class under construction. I'm
guessing mcl comes from __metaclass__ and defaults to type?
the getLogger creates a logging channel so there is one channel per
class? but what selects the class for output or is that a derived
logger class I need to create?
also, how could one automatically determine the method doing the logging?
>
> class Felis:
> __metaclass__ = LoggedType
needed in every top level class?
> def alpha(self):
> self.logger.info("felis-alpha")
>
> class Catus(Felis):
> def alpha(self):
> self.logger.info("catus-alpha")
> def beta(self):
> self.logger.info("catus-beta")
>
> if __name__ == "__main__":
> logging.basicConfig(format="%(name)s.%(funcName)s: %(message)s",
> level=logging.INFO)
> f = Felis()
> f.alpha()
> c = Catus()
> c.alpha()
> c.beta()
>
> If the metaclass bothers you, here's a simpler alternative:
simpler to implement but more error prone. I like the metaclass model.
now if one could fill in the class and method name automatically, life
would be good.
More information about the Python-list
mailing list