Logging in Python – Your One Stop Guide

In today's session of Python programming tutorials, we shall go in-depth in understanding logging and the significance of applying it on various small or big coding projects.

Logging is a crucial step to be performed by a programmer during software development. It helps developers to track events happening during the execution of a program, which can be helpful for the future debugging process. If you are a new learner or working on a new project, it is a good practice to use logging for tracking the code flow and for solving errors.

While writing short programs, most of us typically ignore logging, but when the program becomes complex, then it is an essential and useful step of using logging to fix the errors that prevent the software from running smoothly. Logging is nothing more than writing the events in the software into a log file or outputting in the terminal.

Logging is not only used for debugging. It is also a helpful process for gathering information, gathering usage data, and many other useful tasks. It is also one of the most usual functions for web developers not only to detect errors but also to gather user’s data like IP addresses, which can be used for further business analytics.

In Python, most of the logging facilities are provided by the logging module presented in the python’s standard library, so we don’t have to do any extra configuration. Let’s see how to use it for logging in python. Before following this tutorial, it is necessary to have the latest version of python installed in your system. If you don’t have the newest python installed in your system, you can follow our step by step guide on installing and updating python on Linux.

The Python Logging Module

The python’s logging module is one of the most used logging libraries in python. The best part is that it comes preinstalled with python’s standard library, so we don’t have to do any configuration or installation. The logging module is robust and straightforward, which means that it is useful for both beginners and enterprises. To use the logging module in python, we need to import it into our program as I do in the following line of code.

import logging

Now let us see a demo of how we can log some messages into the terminal. Just copy the following code into your favorite python IDE and run.

import logging
logging.warning("This is a Warning")

On running the above code, we will get the output as shown in the below image.

demo of logging in python

As seen in the output, the program prints a warning message. The logging module also has some other levels of logging like info, error, etc., which make our task easy. Let us discuss them in brief with examples.

Python logging levels

Many levels of logging can be used to log different messages at the level of severity. The levels that are provided by the python logging module are

  • CRITICAL
  • ERROR
  • WARNING
  • INFO
  • DEBUG

These levels are shown in the decreasing order of their severity. Let us see how to use these levels in our program. Just copy the following code and run in the Python IDE.

import logging
logging.critical("This is a critical message")
logging.error("This is an error message")
logging.warning("This is a Warning message")
logging.info("This is an info message")
logging.debug("This is a Debug message")

On running the above code in the IDE, the output that the terminal shows is shown in the below image.

demo of all levels of logging in python

As you can see in the output, the DEBUG and INFO messages are not printed in the terminal because the logging module, by default, logged only the messages of security level higher than or equal to the warning. To display INFO and DEBUG in the terminal, we need to change the Basic configuration of the logger manually. To do so, we can use the basicConfig(**kwargs) method provided by the logging module. To see a simple demo of configuration, just run the following code into your Python IDE.

import logging
logging.basicConfig(level=logging.DEBUG)
logging.critical("This is a critical message")
logging.error("This is an error message")
logging.warning("This is a Warning message")
logging.info("This is an info message")
logging.debug("This is a Debug message")

In the above code, we have set the level of logging.DEBUG, which means that all the levels which are above the debug level will be logged. Thus in the above code, all the messages will be logged as shown in the below image.

configure logging level

Let us discuss more the basicConfig() method of the logging module.

Basic Configurations

The logging module provides a very useful method basicConfig(**Kwargs), which is used for setting configurations for logging data. Some of the commonly used parameters of the basicConfig() function are:

  • level: This is used to set the severity level, which must be logged.
  • filename: This is used to specify the file where we want to log the messages. If we don’t define the file, then it will be logged to the terminal, as we have seen till now.
  • filemode: This is used when we write the logs into a file. These parameters accept the mode in which the log file to be opened. By default, it is set to the ‘a’ mode, which means the file will open in the append mode.
  • format: This is used to format the log message as we need it to display.

Let us see how we can use these configurations in the python’s logging module by exploring the example of one after one.

The level parameter is used to set the level of severity, to see a practical demo of how to use it, copy the below code in the python IDE and run.

import logging
logging.basicConfig(level=logging.INFO)
logging.critical("This is a critical message")
logging.error("This is an error message")
logging.warning("This is a Warning message")
logging.info("This is an info message")
logging.debug("This is a Debug message")

On running the code, you may see the output, as shown in the below image. As you can see that the messages which are above the info levels are printed, but the message at the debug level does not print.

changing configuration of logging

The level parameter is a useful configuration that should be done so that the log files were not too large by containing unnecessary data and have only the required information.

Logging into a file

We have only seen how to log on to the terminal, but logging to the terminal is not always helpful as we can’t save it for later use. For a better solution, we can print the logs in a text file that we save and analyze later. The logs are text and can be kept in a text file of any format, but universally it is adopted to save the logs in a file with the .log extension. These files are known as log files and are used universally for storing logs of programs, web applications, and other software.

We can save logs to a file by setting up the configuration of the logging module with the help of basicConfig() function. We need to give the name of the file where we want to save the logs in the filename parameter of the basicConfig() function, after which the records will be automatically printed in the log file that we specify. Let us see a practical example to know how it works.

import logging
logging.basicConfig(level=logging.INFO, filename="mylog.log")
logging.critical("This is a critical message")
logging.error("This is an error message")
logging.warning("This is a Warning message")
logging.info("This is an info message")
logging.debug("This is a Debug message")

On running the code, you can see that a new file has been created in the current working directory name mylog.log. On opening the file with a text editor, you may notice that the logs were saved into the file.

If we rerun the code, we will see that log will be appended in the file. We can change this by specifying the filemode parameter in the basiconfig() function. By default, the filemode parameter has the value “a,” which stands for append. But sometimes we also want to delete the previously logged data and write the new logs only in the file. For doing this, we can give the filemode parameter the value “w,” which stands for write, and it deletes any previous data in the file and writes the new ones. For a demo, see the following example.

import logging
logging.basicConfig(level=logging.INFO, filename="mylog.log", filemode="w")
logging.critical("This is a critical message")
logging.error("This is an error message")
logging.warning("This is a Warning message")
logging.info("This is an info message")
logging.debug("This is a Debug message")

On running the above code, you may notice that the earlier logs present in the file have been removed from the file, and the new logs have been added. Every time we run the code, the new logs will be added, and the previous will be deleted, which is useful when we don’t need the records for further use.

Formatting the Logs

We have seen the output logs have the default layout, but we can change the format by setting the format parameter of the basicConfig() function. Let us see a practical demo to know how we can use the format parameter in the basicConfig() function to change the format of the log.

import logging
logging.basicConfig(level=logging.INFO, format='%(filename)s: %(levelname)s: %(message)s')
logging.critical("This is a critical message")
logging.error("This is a error message")
logging.warning("This is a Warning message")
logging.info("This is a info message")
logging.debug("This is a Debug message")

The output of the above code is as shown in the below image.

displaying the file name in log

As you can see in the output, the filename has also been displayed. We can use the format parameter for indicating many other formats lets discuss some of them.

%(asctime)s: This is used to display the human-readable time in the logs. To see how it shows time, run the following code in the Python IDE.

import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s : %(message)s')
logging.warning("This is a Warning message")

On running the code, you may see the output, as shown in the below image.

displaying the time in log message

%(created)f: This will display the time in which the log is created.

%(filename)s: This is used to display the name of the file in the log message. To see how it works, just run the following example code in your Python IDE.

import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s : %(filename)s : %(message)s')
logging.warning("This is a Warning message")

The output that the code provides is shown in the following image. In the output, the name of the file has been displayed. This is useful while working on a project which involves multiple files so we can get the file that has the error quickly.

displaying the filename in log message

%(levelname)s: This is used to display the name of the level used like WARNING, DEBUG, etc.

%(levelno)s: This is used to print the numeric value of the level that the message is a part of.

%(lineno)d: This is used to print the line number of the current line, which displays the message. This is very useful as it gives us the line number where we must-see for an error, so it helps the debugging process. Let us see an example code to see how to use this to form the output of logs.

import logging
Format = '%(asctime)s : %(filename)s:%(lineno)d: %(message)s'
logging.basicConfig(level=logging.INFO, format= Format)
logging.warning("This is a Warning message")

This code will also print the line no, as shown in the below image.

displaying the line number in log

%(message)s: It is used to display the message that we have logged.

%(pathname)s: This is used to display the full pathname of the source code file.

%(process)d: This will display the process id if available.

%(processname)s: This will display the process Name if available.

%(thread)d: This will display the Thread id if available.

%(threadName)s: This will display the Thread Name if available.

Logging Variable Data

We have given the messages in the logs by ourselves, which are static data. Still, in real-world applications, the data we logged will be mostly dynamic information from our application. To do this, we need to output the variables with the message log. We can do this in many ways. For example, we can include the variables and format the string with placeholders and then pass them to the message log so that the values of the variables will be output in the records.

For example, see the below code; you can copy the code an run in your python IDE.

import logging
var_message = "internal Error"
logging.warning("The server has been stopped due to %s", var_message)

On running the code, you will see the output, as shown in the below image. As you can see in the picture that the value stored in the variable is also printed on the screen.

displayng variable in log message

We can also display variables in logs using the f-strings, which are introduced in python 3.6. But to use the f-strings, you will need python 3.6 or greater installed in your system. You can check which python version is installed in your system by running the following command in the terminal.

python --version # for python 2 on Linux
python3 --version # for python 3 in Linux

This will print the version of python you are using in your system. It is a good practice to use the latest version of python to get better performance; you can see our guide to updating your python version in Linux.

To format strings using the f-strings in python, we need to use the following code syntax. You can copy and run the code in your favorite python IDE.

import logging
var_message = "internal Error"
logging.warning(f"The server has been stopped due to {var_message}")

On running the code, you will get the output similar to the one we get on running the above code. But when we see the code, we can notice the f at the beginning of the string, which represents that it is an f-string, and we can directly use variables in f-strings by putting them in curly braces.

Logging Stack Traces

The logging module can also be used for capturing stack traces. Stack traces are the exception messages that are thrown when an error has occurred in the program. We can capture the exception by setting up the exc_info parameter to True while calling the logging function. This parameter is useful as we can log the complete exception message with our error message in a file or terminal screen.

To get a practical demo to know how we can lof the stack traces, copy the following code into your python IDE and run.

import logging
try:
    a = 1/0
except Exception as e:
    logging.error("An Error has been Occured", exc_info=True)

On running the code, the exception will be logged in the terminal. You will see the output of the code, as shown in the below image. You can also log the exception into a file using the filename parameter in the basicConfig() method, as we discussed above.

logging exception in python

This method is also critical in building the extensive application as we can have exception handling with logging, which is excellent for the debugging process.

Logger Objects

The logging module also provides some useful classes which can be used for better logging, mainly for a broader application. Let us see some of the most used classes of the logging module and what and how they function.

  • Loggers: The Logger class is the class whose objects are used to call the functions directly.
  • Handlers: Handlers are used to send the log messages to the desired output location i.e., file or console.
  • Filters: This is used to filter the display of log records.
  • Formatters: These were used to format the output of the logs messages.

If you want complete detail on how to use these classes, you can refer to the official documentation of the python logging module.

Conclusion

In this article, we have learned the basics of doing logging in python. The logging module is a straightforward and powerful way to do logging in python. Suppose you are not doing logging till now, today is the day to get started with logging as you read the article and learned how easy it is to use logging in python. You can now use logging in both small and significant applications.

If you do logging correctly, it will indeed be helpful in one way or another. I advise you to start using it from small programs as it will help you to get a good knowledge of the thing or two and will be priceless for big projects. You may also want to see how to work with SQLite databases in python. 

Roshan Agarwal
Roshan Agarwal is a python programmer and Linux lover; he is using and experimenting with python for a long time. He loves to write and review open-source software, command-line tools, and web applications. Apart from writing tutorials, he explores and contributes to open-source programs in GitHub.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

STAY CONNECTED

23,241FansLike
394FollowersFollow
16SubscribersSubscribe

LATEST ARTICLES

MUST READ

The Ubuntu Cinnamon Remix brings together Linux Mint's Cinnamon desktop with the Ubuntu Core. While some users are welcoming the new flavor of Ubuntu with open arms, others are scratching their heads, wondering where it fits in.
The wait is finally over (almost) for all you Ubuntu fans out there. The latest version of Ubuntu, 20.10 codenamed "Groovy Gorilla," is currently available in the beta version. I have tested out the distro myself, and it is stable enough to take out for a spin.

Top 10 Reasons to use Xfce as your Desktop Environment

There are many choices for desktop environments for Linux based operating systems. Mainly, you can install any DE of your choice on most of the Linux based distributions, even if they are not offered as a package officially. In our recent articles, we discussed the best of KDE and Cinnamon. In this article, we wish to present to you the top reasons why you should consider Xfce as your desktop environment.

3 Best Ways to Uninstall Software on Ubuntu

Uninstallation of programs can be done by graphical way using the Ubuntu Software Center, and the Synaptic Package manager. Command-line way of doing it is also possible using apt-get and aptitude commands. We shall discuss each one of them in detail.

Test drive a Linux distro online before you hate it

Enter DistroTest.net, a website that allows Linux users to test various distros online, without downloading the ISO or installing the distro. With DistroTest.net, you can check a distro with no muss, no fuss.

Pop!_OS 20.04 Review: Professional Linux Distribution Ever Made

Linux is growing faster than ever. As per the latest report, there is a drop in the Windows 10 market share for the first time, and Linux's market share has improved to 2.87% this month. Most of the features in the list were rolled out in the Pop OS 20.04. Let's a detailed look into the new features, how to upgrade, and a ride through video.