Member-only story
Power-Up Your Python Logging
A guide to take you from beginner to pro with Python’s built-in logging tools

Debugging a large application sucks. Especially when you have a bug that shows itself in production but can’t be reproduced in the dev environment. Finding these can be made easier with the use of Python’s built-in logging tools.
This guide is designed to help newcomers understand Python’s logging module. Heaven knows it confused me when I first started. In the end, we will have a working logger that is able to throw errors to a discord channel.
The code for this problem can be found in the civicsoft/ieddit GitHub repository.
Quick Overview of Logging
One note before we get into logging: both loggers and handlers below use, what we call, levels. This is a hierarchy of how things are handled.
For example, when we set a handler to the DEBUG
level, it will receive debug statements and all the levels above it. These levels are used to filter data by its importance.

Loggers
A logger is simply a named instance of the logging object. All loggers are “global” within your program. Here is an example of what that looks like.
We have defined a logger named app
in app.py
.
# ieddit/app.pyimport logging
logger = logging.getLogger("app")
Now, if we wanted to, we could drop into another file and have access to that same logger instance we created before.
This is what that would look like:
# ieddit/utils.pyimport logging
logger = logging.getLogger("app")
Now the utils.py
has access to that same logger instance! This means that we can declare all the loggers we want before they are ever needed, which we will see a little later.
Side note here: the best practice is to use the __name__
attribute for naming loggers like this: logging.getLogger(__name__)
. This way, each file…