Capturing Stack Traces
The logging module also allows you to capture the full stack traces in an application. Exception information can be captured if the exc_info
parameter is passed as True
, and the logging functions are called like this:
import logging
a = 5
b = 0
try:
c = a / b
except Exception as e:
logging.error("Exception occurred", exc_info=True)
Here’s what you’d get:
ERROR:root:Exception occurred
Traceback (most recent call last):
File "exceptions.py", line 6, in <module>
c = a / b
ZeroDivisionError: division by zero
[Finished in 0.2s]
If exc_info
is not set to True
, the output of the above program would not tell us anything about the exception, which, in a real-world scenario, might not be as simple as a ZeroDivisionError
. Imagine trying to debug an error in a complicated codebase with a log that shows only this:
ERROR:root:Exception occurred
00:00
It’s great being able to log events, but what if we want to log something critical, like a crash? We can do that by logging the stack trace. All we have to do is pass the exc_info
parameter, short for exception info, as True
.
00:18
We can pass this to any of the severity level functions. If exc_info
is False
, the exception won’t be included in the log, just the message.
00:30
Here’s an example of this in action. In this code, I’m trying to divide 5
by 0
, which as you can probably guess is going to raise a ZeroDivisionError
.
00:41
If you’re not familiar with exceptions, I’d highly recommend you check out our video course on Python exceptions by Darren Jones. But basically, Python will try to divide 5
by 0
, realize that it can’t, and then instead of just crashing, it will first log the exception.
00:59
That’s the last line that says logging.error('Exception occurred', exc_info=True)
.
01:08 Now, when we look at the output, we’ll see the standard log output for an error, as well as the stack trace beneath it. This is a lifesaver in a large-scale application with lots of moving parts.
01:22
Could you imagine if the only log output we saw was Exception occurred
?
01:28
Alternatively, instead of passing the exc_info
parameter to one of the severity level functions, we can simply call logging.exception()
.
01:38
This is the equivalent of saying logging.error(exc_info=True)
. That means that logging.exception()
uses the level of ERROR
.
01:50
If you want to use a different level, add the exc_info
parameter to that level’s function, like we did before. logging.exception()
is only a shorthand for logging ERROR
level events.
02:03 Next, let’s see how we can create our own custom loggers.
Bartosz Zaczyński RP Team on Oct. 8, 2023
@Mario Cortés In my experience, using some form of logging has always been practiced. It’s important to remove sensitive information like passwords or secret keys from the logs once they’re saved to a file or sent somewhere to the cloud.
Become a Member to join the conversation.
Mario Cortés on Oct. 6, 2023
So, is logging the best practice for capturing the Stack Traces in production applications?