The logging package can log exceptions and call stacks, but it does (in my opinion) a suboptimal job of it. Consider this simple example:
>>> import logging >>> FORMAT = '%(asctime)-15s %(levelname)s %(message)s' >>> logging.basicConfig(format=FORMAT, force=True) >>> log.warning("msg", stack_info=True) 2021-02-06 20:46:52,399 WARNING msg Stack (most recent call last): File "<stdin>", line 1, in <module> It formats the warning message just fine, but simply dumps the traceback onto the stream with no timestamp or level. For my purposes, this is more important for exceptions. (I'm just using the stack trace feature as it's easier in a small example.) I would like to call something like log.exception("Some message...") and find something like this in the output stream: 2021-02-06 20:46:52,399 ERROR Some message... 2021-02-06 20:46:52,400 ERROR Traceback (most recent call last): 2021-02-06 20:46:52,402 ERROR File "<stdin>", line 1, in <module> That way I can more easily grep log files for errors and get the entire detail, including the traceback. It seems I have to subclass logging.Formatter to override formatStack or formatException, then construct the individual lines of output, set handler and formatter, blah blah blah. I'm pretty sure I've done this in the past by writing my own little log_exception method which formats the exception and calls log.error for each row of the traceback. That seems easier than the "right" way. That seems harder than it ought to be. Hopefully I'm just missing something simple. Skip -- https://mail.python.org/mailman/listinfo/python-list