Python Global Logger
This tutorial introduces logging, its various levels, and its importance in Python. Then, we’ll learn how we can use Python logging
module globally.
Introduction to Logging and Its Importance in Python
Logging is a way to track events that happen while running the software. The software developers add logging calls to log the errors and events that occur when someone executes the program.
In Python programming, we have a built-in module known as logging
that can log such errors and events. Note that events are the message and can optionally hold data that is specific to an event.
These events can be of different levels/severity, assigned by a software developer. So, we can say that logging is a very powerful tool to debug our application and track any needed information.
The logging
module provides us with different methods for our application to configure various log handlers, route log messages to these handlers, and enable highly flexible configuration, which aids in handling various use cases.
The logging
module also has different log levels, which help us deal with various severity levels. Following is a brief description of the logging levels:
INFO
- It confirms that various things are working as expected.DEBUG
- It provides detailed information typical of interest when someone diagnoses the problems.WARNING
- It is an indication of something happening unexpectedly. We can also say thatWARNING
indicates a problem that may happen shortly, for instance, low disk space.CRITICAL
- It indicates a serious error that the application itself cannot continue executing.ERROR
- It represents a more serious issue that does not allow the program to perform an operation or function.
Use the logging
Module Globally in Python
We can use the logging
module locally and globally in Python. Here, locally means to use the logging
module in a specific scope; for instance, we import the logging
module in the A.py
file, so we can only use that in A.py
, not in the B.py
file.
On the other hand, globally means using everywhere in the A.py
file and B.py
file. It is important to understand the use of the logging
module locally to learn Python global logger.
Example Code Using logging
Module Locally (saved in the test.py
file):
import logging
logger = logging.getLogger("test_logger")
logger.setLevel(logging.INFO)
def sum_numbers(number1, number2):
try:
output = number1 + number2
except TypeError:
logger.exception("Oh! TypeError Occurred")
else:
return output
result = sum_numbers(10, "Mehvish")
Here, we are using the logging
module locally in the test.py
file, which we have imported.
Then, we use getLogger()
to begin logging using the logging
module in Python. The factory function logging.getLogger(name)
is executed for that.
The getLogger()
takes one argument, which is a logger’s name, and returns the reference to the logger instance (object of logger) with the name if specified or root
if not.
Note that multiple calls to the getLogger()
with the exact name return the reference to the same logger instance, which is useful for using it globally (we will see that in a while).
Next, we use the setLevel()
method to set the level of logging and write the sum_numbers()
function, which takes two int
type numbers, adds them, and returns the result if the correct values are given; otherwise, it generates TypeError
.
Finally, we call sum_numbers()
to see our logging
module in action by producing the following results.
OUTPUT:
Oh! TypeError Occurred
Traceback (most recent call last):
File "E:\Code\use_logging_locally\test.py", line 8, in sum
output = number1 + number2
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Using the logging
module is very easy, but how to get an advantage of this module globally? Let’s learn that below.
Example Code (saved in the log.py
file):
import logging
def set_custom_logger(name):
formatter = logging.Formatter(
fmt="%(asctime)s - %(levelname)s - %(module)s - %(message)s"
)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
return logger
Example Code (saved in the submodule.py
file):
import logging
logger = logging.getLogger("root")
logger.debug("submodule message")
Example Code (saved in main.py
file):
import submodule
import log
logger = log.setup_custom_logger("root")
logger.debug("main message")
OUTPUT:
2022-10-27 09:31:02,447 - DEBUG - main - main message
2022-10-27 09:31:02,450 - DEBUG - submodule - submodule message
This code sample prints the date, time, logging level, module name, and message. Note that we used logging.getLogger()
in submodule.py
to use the exact logger instance we used in the log.py
file.
How? The logging.getLogger(name)
is typically run to begin logging using the logging
module in Python. The getLogger()
accepts one argument, the logger’s name.
By using the getLogger()
function, we get a reference to the logger instance with the given name if provided, or root
, if it is not specified.
Making multiple calls to the getLogger()
having the exact name returns the reference to the exact logger object, which helps us to use it globally.