[Python-Dev] PEP282 and the warnings framework

holger krekel pyth@devel.trillke.net
Thu, 16 May 2002 00:33:21 +0200

Kevin Butler wrote:
> The logger instance contains the category (I forget if we call Logger 
> constructors or call a factory method):
> 	logger = Logger( "pil.image.jpeg" )
> 	logger2 = Logger( "pil.image.gif" )
> 	logger.debug( "My JPEG Image PIL Debug message" )
> 	logger2.error( "My GIF image PIL error message" )
> The logging of theses message is configurable based on the "pil" category, the 
> "pil.image" category, the "pil.image.jpeg"/"pil.image.gif" category, and their 
> priority.

i don't think you read my last posting. This logging-instance behaviour 
is *fine* but it is ortoghonal to whether an integer or a type characterizes
a message. You example would work *without* change.

> To get similar functionality with a message-based hierarchy, I'd have to 
> define separate "PilImageJpegMessage" and "PilImageGifMessage" classes, and 
> have them both extend a PilImageMessage class.

No, far from it. 

> >     (The base Message class should accept Exceptions and Strings IMO.)
> FWIW, once you allow logging 'string'-type messages, most logged messages will 
> be a string (especially debug messages), because it is much easier than 
> creating an instance of some other clsas.  Thus, if your categorization is 
> based on the class of the logged message, the "string" category gets very large...

NO. Only because a typed message accepts a string in its constructor 
does not make it a string. Or since when are all python exceptions 
in the 'string' category? 

> > This doesn't touch the question how messages
> > should be categorized (by integer or by class-type).
> The question, as I understood it, was whether to categorize by 
> message-class-name, or by logger-instance-category.

no. it is whether Messages are characterized either by
string/integer or Message-instance/type.

> Although the 'message-class' hierarchy appears attractive, logger-instance 
> categorization has been more useful to me.

logger-instance filtering/categorization DOES NOT suffer.

But you gain more control e.g. how expensive your logging gets. 
If you want to e.g. trace the state of certain objects
you define a TraceStateMessage and defer the actual 
(expensive) introspection until __str__ is called on the 
message [*]. 



In basic code words:

class TraceStateMessage(DebugMessage):
    def __init__(self, obj):

    def __str__(self):
        """ this is called only if someone is interested in the message """
        names = filter(lambda x: not x.startswith('_'), dir(self.obj))
        d = map(lambda x: (x,getattr(self.obj, x)), names)
        return "%s, attrs: %s" %(type(obj),d)
log.traceobj = lambda self,obj: self.log(TraceStateMessage(obj))

Now you can can do 


easy & straight forward. Doesn't touch the categorization
configuration of 'log' at all: if it wants to see DebugMessages
then introspection is done, otherwise overhead is minimal.