[Python-Dev] PEP282 and the warnings framework
Wed, 15 May 2002 09:51:26 -0600
> And looking at the warning framework suggests a different way
> of handling log levels/types: Instead of specifying types
> with integer constants and configuring what to log with a
> threshold value, we could have a class hierarchy of message
> types similar to the hierarchy for warning types:
> class Message(Exeption):
> class InfoMessage(Message):
> class ErrorMessage(InfoMessage):
> class FatalMessage(ErrorMessage):
> This hierarchy is customizable with user defined classes:
> class ResourceMessage(FatalMessage):
> class DiskFullMessage(ResourceMessage):
> class OutOfMemoryMessage(ResourceMessage):
We could, but it would be a mistake. :-)
Subclasses should differ in behavior - if they differ only in data, that data
should go into attributes instead. (Yes, this is disputable, but it does tend
to simplify designs.)
The Info/Error/Fatal classes differ only in name (with the name mapping to a
'severity'), making it more appropriate for them to be distinguished by some
sort of 'severity' attribute. Similarly for the message subclasses (with a
name mapping to 'message type').
Having struggled with a message-hierarchy-based system, I found that:
- Programmers tend to avoid creating a new subclass just to log a new message.
This results in lots of inappropriate reuse of the existing message classes,
or hesitancy to log a message at all, reducing your ability to configure
individual sets of messages you're interested in. This is similar to the
hesitancy to create a new exception subclass, but seems to be stronger -
probably because you never 'catch' the logged messages, so the
presence/absence of the class doesn't simplify/complicate other code. In
contrast, creating a new Logger (or "Category") instance meets little
resistance, and a shift to that model was welcomed by all...except the
developer of the message hierarchy logging system.
- Some messages are awfully hard to categorize statically: the severity of a
FileNotFound message could be FATAL, WARNING, or DEBUG, depending on what file
is not found and the error-handling code around the message, so you end up
needing multiple FileNotFound message classes. Thus, it is better for the
calling code to determine the severity of a message, rather than some static
property of the message itself.
- Configuring logging by message type is usually less helpful than enabling
messages from a specific area of code, so configuring by package or class
tends to be more useful.
I think the ideal would be to enable logging per thread, based on execution
path: 'log all messages from any thread that has Class1.method2 in its
stack', but I haven't worked with that yet.