[issue6435] logging: cache the traceback text on formatter, instead of record

Sridhar Ratnakumar report at bugs.python.org
Thu Jul 9 10:06:36 CEST 2009

Sridhar Ratnakumar <sridharr at activestate.com> added the comment:

> 2. The exception text needs to be stored in the record, because in some
> instances (e.g. pickling and sending over a socket) this information
> will not be available at the other end in any other way.

Caching in the record object is thus the way to go. But the cache needs to  
be invalidated when `exc_info` is changed .. as in set to None when it was  
a traceback object. I'd change the following:

         if record.exc_text:
             if s[-1:] != "\n":


         if record.exc_info and record.exc_text:
             if s[-1:] != "\n":

(or, move the body of this IF to the preceding IF)

> 3. The way it works now, if you have multiple formatters attached to
> multiple handlers (e.g. with ISO time for log files, with no ISO time
> for console output), then the traceback is only converted to text once.

Yes, that is the benefit of caching I see.

> 4. There's nothing stopping you from overriding Formatter.format, is
> there? the base version uses the cache, you can override format in your
> custom formatter and ignore the cache altogether if you like.

I can, but I'd rather not duplicate that code. From the recipe I linked  

     def format(self, record):
         # attach 'error:' prefix to error/critical messages
         s = logging.Formatter.format(self, record)
         if record.levelno >= logging.ERROR:
             return 'error: {0}'.format(s)
             return s

Here, I simply call the base class's `format` method.

And do you know of a better way to suppress traceback output (in the  
custom handler during `log.exception`) than the hack used in the recipe?

         elif record.levelno >= logging.ERROR:
             if record.exc_info and self.verbosity_level < 1:
                 # supress full traceback with verbosity_level <= 0
                 with new_record_exc_info(record, None):
                     self.__emit(record, sys.stderr)
                 self.__emit(record, sys.stderr)

.. http://code.activestate.com/recipes/576836/


Python tracker <report at bugs.python.org>

More information about the Python-bugs-list mailing list