[Python-Dev] PEP282 and the warnings framework

Kevin Butler kbutler@campuspipeline.com
Wed, 15 May 2002 18:29:05 -0600


holger krekel wrote:
> Kevin Butler wrote:

> 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.

I read it, but I obviously didn't understand it as you meant it.  :-)

*deep thought*

I don't see how it would work without drastically increasing the configuration 
complexity.

	log = logging.getLogger( "pil.image.gif" )
	log.log( IOError( reason ))

Currently, I can configure the hierachy pil...image...gif, and I can specify 
the integer priority level below which I won't log a message in that category.

If you add the hierarchy 
IOError...EnvironmentError...StandardError...Exception, how do you decide 
whether to log the message or not?

- Do you have two separate hierarchies, making each message enabled/disabled 
for all loggers?  This doesn't seem to give you much flexibility (IOError 
enabled everywhere).

- Or does each logger configuration have a hierarchy of message types, and 
each message type can be enabled/disabled for each logger?  (This seems to 
require too much configuration.)

Some other approach I'm not seeing?

>>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? 

If I have a choice between writing:

   log.debug(
     "HOME environment variable set to non-existent directory %s",
     homedir
     )

and:

   log.debug( ConfigurationException(
	"variable set to non-existent directory",
	"HOME",
	homedir
	))

I'm most likely to just use the string option - and
if I don't have a 'ConfigurationException' class & constructor that exactly
matches what I need, I'm even more likely to just log the string.

> 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 [*]. 

The API discussions already allow deferred rendering using *args,
specifically to avoid expensive rendering that isn't needed.

http://www.red-dove.com/python_logging.html

You can get approximately the TraceStateMessage example you provided by just 
doing the following (formatting differs, yada-yada-yada):

	trace = logging.getLogger( "trace" )
	trace.debug( "%s, attrs: %s", type( obj ), obj.__dict__ )

And you can get /exactly/ the TraceStateMessage example, including formatting, by:
	#
	# TraceStateMessage class you defined	
	#

	trace = logging.getLogger( "trace" )
	trace.debug( "%s", TraceStateMessage( obj ))

Configuring on both MessageType and Logger (category) seems like unneeded 
bloat to me.

kb