[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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4