0

A great way to process exceptions is to use Logger.exception:

try:
    do_something()
except BaseException:
    logger.exception('some message')

... this not only prints out the user message, but also the exception message and exception type, and also a full stacktrace.

My logger here has two handlers: a FileHandler and a StreamHandler.

Using colorlog to colour my logger output according to the various levels, I can see that in the above case "some message" is printed according to the logger (level logging.ERROR I believe, i.e. red)... but the stacktrace itself is printed in ordinary console colours. It could be stdout, but more likely to be stderr.

As it happens, I want this stacktrace in such cases to be printed out in full to my logger's file handler, but not to the stream handler which handles console output: stacktraces are fantastic for debugging purposes but by default the user shouldn't be exposed to them.

I looked at logging docs on StreamHandler, but couldn't see a way to suppress this stacktrace printout for a given such handler.

Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191
mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • Part of it is already there; `except BaseException as e:` will give you the exception message bound to `e` without the traceback. As to how to switch the logger in the cleanest way, I'm less sure – roganjosh Apr 16 '23 at 13:54
  • If I understand, you're saying use `logger.error` and handle your own stack extraction and reporting. But the point is that I want to take advantage of `logger.exception`, which is so well designed for this purpose. Having a look at the `logging` module source code but, as ever, it's quite complex. Suppressing the stack trace in a console stream handler is a fairly intuitive thing you'd want to be able to do. – mike rodent Apr 16 '23 at 14:10
  • Suppressing the stack trace is done for you if you `except SomeException as e:` and just log `e`. You're suggesting that you want to log the error but not the traceback, so log `e` with an exception level `INFO`/`WARN` etc. The fact that you're logging it on the exception level probably means you'll get the stack trace anyway. This is not my strong area but I'm not sure you can have it both ways; if you want the error but no traceback, and for the program to continue, should you be using `logging.exception`? – roganjosh Apr 16 '23 at 14:14
  • Ah, perhaps I didn't clarify enough: my logger has TWO handlers, a StreamHandler (console output) and a FileHandler (log file output). I want the stacktrace logged in the latter but don't want the user with the console in front of them to see that stacktrace. There are obvious ways of doing this without using `logger.exception`, but an elegant way to get what I want would be if the stacktrace output could be suppressed for a handler. I'm fairly optimistic about subclassing `StreamHandler` to achieve this. – mike rodent Apr 16 '23 at 14:18

1 Answers1

-1

To suppress the stack trace for a particular handler, attach a formatter to that handler that returns e.g. an empty string for the stack trace. See my relevant answer here to another question - that answer formats the stack trace into one line, but you should be able to extend the idea presented there.

Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191