[Python-Dev] Re: PEP 282 comments
Trent Mick
trentm@ActiveState.com
2002年3月21日 00:46:05 -0800
[Jeremy Hylton wrote]
> It seems quite plausible to decide to log an exception and
> then get another trivial exception raised and caught on the
> way to the logger. You would still want to log the original
> exception, so passing it explicitly is helpful sometimes.
Yes, I suppose so.
> If I would implement debug() and other helper methods, I'd
> still like to see it as a keyword argument. I assume the
> various methods would be connected something like this:
>> class Logger:
> def log(self, msg, level, exc=None):
> "Log msg at level w/ optional traceback for exc."
>> def debug(self, msg, exc=None):
> self.log(msg, DEBUG_LEVEL, exc)
>> def exception(self, msg, exc=None):
> if exc is None:
> exc = sys.exc_info()
> self.log(msg, ERROR_LEVEL, exc)
>> This doesn't seem complicated or particularly slow.
Yup, I agree. Except it'll look like this:
class Logger:
def log(self, level, msg, *args, **kwargs):
"Log msg at level w/ optional traceback for 'exc' keyword arg."
if level < self.getEffectiveLevel():
return
# construct LogRecord
# pass LogRecord onto appropriate Handlers
def debug(self, msg, *args, **kwargs):
self.log(DEBUG, msg, *args, **kwargs)
def exception(self, msg, *args, **kwargs):
if not kwargs.has_key("exc")
kwargs["exc"] = sys.exc_info()
self.log(ERROR, msg, *args, **kwargs)
Jeremy,
The methods use 'msg, *args' instead of just 'msg' to avoid string
interpolation if the message will not be logged. I think that that is still
important to keep, albeit it making the 'exc' keyword argument less explicit.
Vinay,
Here is why I really like this idea now. As per usual, any log message call
has the 'msg, *args' arguments. But, in addition, arbitrary objects can be
passed in as keyword arguments. These objects get slapped into the
LogRecord's __dict__ and any subsequent Handler and/or Formatter can work
with those objects. For example, if I want to log some arbitrarily complex
object I can just add it to the log record. On the handling end, I could have
a Formatter that knows how to deal with that object. For formatters that
*don't* recognize certain objects, a reasonable default like using the pprint
module could be used.
Granted this isn't as generic as log4j's ObjectRenderer system but it allows
the system to grow into that cleanly.
Pros:
- Jeremy is happy, he can easily log exceptions to specific levels using
the nice info(), debug(), etc. routines.
- logger.exception("Eeek: %s", arg) is there for easy use
- logger.exception("Eeek: %s", arg, exc=sys.exc_info()) is there when one
need be explicit about where exc_info comes from.
Cons:
- The signature ...**kwargs... doesn't make it clear that a special key
for exception info will be handled.
- This could be construed as too much generality. It may complicate the
LogRecord and Formatter in that they have to deal with arbitrary keyword
args. (Mind you, I don't think that that needs to be any issue. For a
first pass any keyword arg other than 'exc', or whatever it is called,
could be ignored.)
Trent
--
Trent Mick
TrentM@ActiveState.com