Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should logger.exception only be called inside an except block? Why?

The docs for logger.exception mention:

This method should only be called from an exception handler.

So usage should look something like this:

try:
    errorerrorerror
except NameError as e:
    logger.exception('debug message %s', e)

But when I tried doing it the "wrong" way, behaviour seemed to be just the same:

try:
    errorerrorerror
except NameError as e:
    pass

logger.exception('debug message %s', e)

What is the reason for that caveat mentioned in the docs? Is it actually true that we can only use it in an except block, for some subtle reason not evident here?

like image 953
wim Avatar asked Jul 17 '14 11:07

wim


People also ask

What does logger exception do?

Logging an exception in python with an error can be done in the logging. exception() method. This function logs a message with level ERROR on this logger. The arguments are interpreted as for debug().

Does logger exception raise an exception?

It depends on the situation, but logging and then raising an exception is generally considered an antipattern. It's redundant and clutters logs. Unless you're expecting something to catch that exception and suppress the message, don't log.

What is the use of logger in Python?

Logger : This is the class whose objects will be used in the application code directly to call the functions. LogRecord : Loggers automatically create LogRecord objects that have all the information related to the event being logged, like the name of the logger, the function, the line number, the message, and more.

How do you log unhandled exceptions in Python?

First, you will create a logger that will take care of your exceptions. Then create a handler handle_unhandled_exception that you will later attach to the hook. Then call the __excepthook__ provided by the sys module. This method is invoked every time the exception is uncaught.


1 Answers

The method is designed for use in an exception handler. As such the documentation tells you this, by using the word should, not must.

In the text of standards, should and must are rigidly defined; one means we advice you to do it this way, it'd be much better if you did, the other means it's an outright error if you don't do this. See RFC 2119 for the IETF taskforce wording.

All logging.exception() does is set the exc_info keyword argument before calling logging.error(). The exc_info argument is then later fleshed out to include the most recently handled exception, taken from sys.exc_info(). It is then up to the formatter to include the exception message (via the Formatter.format_exception() method) to format the exception.

Because sys.exc_info() works both in the except suite and out, both variants work. From a code documentation point of view, it is just clearer if you use it in the except handler.

You don't need to include the error message, really, because your log formatter should already do that for you:

logger.exception('debug message 2')  # exception should be included automatically

You can explicitly attach an exception to any log message with:

logger.error('debug message 2', exc_info=sys.exc_info())

or any other 3-tuple value with the exception type, the exception value and a traceback. Alternatively, set exc_info=1 to have the logger retrieve the information from sys.exc_info() itself.

See the documentation for Logger.debug():

exc_info which, if it does not evaluate as false, causes exception information to be added to the logging message. If an exception tuple (in the format returned by sys.exc_info()) is provided, it is used; otherwise, sys.exc_info() is called to get the exception information.

like image 150
Martijn Pieters Avatar answered Sep 28 '22 05:09

Martijn Pieters