How to create Logs in Python?

Posted in /  

How to create Logs in Python?
vinaykhatri

Vinay Khatri
Last updated on April 18, 2024

    Log file comes in very handy when we want to track all the events performed by our application. Using the log file, we come to know everything about the program history, bugs, warnings, and errors if there are some.

    Although we can use simple print() statements in our Program to display the flow of the program, but when it comes to large programs, it is always a good practice to use the log files to track the working flow of the Program.

    In this Python tutorial, you will learn how to create log files in Python using the Python logging module.

    Python logging Module

    logging is a Python standard module, which means it comes pre-installed with Python. We do not need to install it using the pip install command. This module provides a fast and flexible way to generate log files using Python to track the working of the program. This module provides 5 levels of standard logging, DEBUG , INFO , WARNING , ERROR , and CRITICAL . And using these 5 levels, we can show different types of messages on the log file.

    Logging Levels Description Numeric Value
    DEBUG It is used to show the messages for diagnosing problems. 10
    INFO It displays messages when everything is working fine. 20
    WARNING It is used to indicate the problems which are unexpected, are the program is still working. 30
    ERROR It is used to indicate the problem where the program is not able to perform the task. 40
    CRITICAL It indicates the situation when the program is in serious problem and no longer able to execute further. 50

    Until we config the logfile we can print all the log messages on the terminal or console panel like a print statement using the following methods.

    • debug()
    • info()
    • warning()
    • error()
    • critical()

    Example

    import logging
    logging.debug(" This is a DEBUG message")
    logging.info(" This is an INFO message")
    logging.warning(" This is a WARNING message")
    logging.error(" This is an ERROR message")
    logging.critical(" This is a CRITICAL message")

    Output

    WARNING:root: This is a WARNING message
    ERROR:root: This is an ERROR message
    CRITICAL:root: This is a CRITICAL message

    Behind the code

    You might be wondering the console only prints warning() , error() and critical() messages not info() and debug(). This is because, by default, the logging standard is set to Warning, which means it only logs Warning and above values such as Error and Critical, and ignores Debug and Info.

    This behavior of logging can be changed by configuring the logging basicConfig() method that we will discuss in the next section. Until we define the log file, all the log methods will try to log all the messages on the terminal or command prompt.

    Logging Basic Configuration

    The logging module also provides basicConfig() method, that helps us to change the working of the overall logging module. This method can be treated as a mini version of logging settings.

    Syntax

    basicConfig(filename, filemode, level, format, datefmt, handlers)
    • filename represents the file name of the log file.
    • filemode represent the writing mode of logs by default. Its value is "a" that specify append it can also be changed to "w" for write.
    • level represent the level of logging, by default, its value of Warning that's why it only log warnings and above values. It can accept values like logging.DEBUG , logging.INFO , logging.WARNING , logging.ERROR and logging.CRITICAL .
    • format represent the string to format the log message.
    • datefmt is used to format the date-time in logs.
    • handlers represent the logging handlers. By default, it is handled by the root user.

    Change the logging level

    In the above example, we were only able to log Warning and above messages on the console because, by default, the logging level is set to Warning. Now using the basicConfig() method we can set the logging level to DEBUG then, which logs all the logging messages.

    Example

    import logging
    
    #config the default level to debug
    logging.basicConfig( level=logging.DEBUG)
    
    logging.debug(" This is a DEBUG message")
    logging.info(" This is a INFO message")
    logging.warning(" This is a WARNING message")
    logging.error(" This is a ERROR message")
    logging.critical(" This is a CRITICAL message")

    Output

    DEBUG:root: This is a DEBUG message
    INFO:root: This is a INFO message
    WARNING:root: This is a WARNING message
    ERROR:root: This is a ERROR message
    CRITICAL:root: This is a CRITICAL message

    In basicConfig() method must be defined before using the other log message methods. In the above example, we configure the default level to DEBUG, which allows us to print or log all the level messages on the console.

    Change logging format

    When we log all the messages on the console, it adds the prefix level name root: before the message, we can change this format to our own unique format by specifying the format parameter in the basicConfig() method.

    Example

    import logging
    
    #config the default level to debug
    logging.basicConfig(
    level=logging.DEBUG,
    format = "%(asctime)s - %(levelname)s - %(message)s", #time level message
    )
    logging.debug(" This is a debug message")
    logging.info(" This is a INFO message")
    logging.warning(" This is a WARNING message")
    logging.error(" This is a ERROR message")
    logging.critical(" This is a CRITICAL message")

    Output

    2021-03-14 11:42:07,191 - DEBUG - This is a debug message
    2021-03-14 11:42:07,196 - INFO - This is a INFO message
    2021-03-14 11:42:07,198 - WARNING - This is a WARNING message
    2021-03-14 11:42:07,200 - ERROR - This is a ERROR message
    2021-03-14 11:42:07,201 - CRITICAL - This is a CRITICAL message

    After setting the format parameter to "%(asctime)s - %(levelname)s - %(message)s" the log messes, print in time - level -message format. %(asctime)s represent current date time %(levelname)s represent the level of logging %(message)s represents the message. There are many formats available for logging, such as

    • %(created)f represent the created time of log record
    • %(filename)s pathname of the log file.
    • %(levelno)s the numeric value of the level
    • %(module)s name of the module.

    you can check all the available LogRecord Attributes here.

    Create a Log file

    By far, we have been printing or logging all the logs on the terminal or console window because we have not specified the log file. Now let's create a Python program that will generate a log file and store all the logs in that file instead of printing them on the console window.

    Example

    import logging
    
    #config the default level to debug
    logging.basicConfig(
        filename = "division.log",
        level=logging.DEBUG,
        format = "%(asctime)s - %(levelname)s - %(message)s",   #time level message
    )
    
    def division(num1, num2):
        logging.debug(f"dividing {num1} by {num2}")
        try:
            result= num1/num2;
            logging.info(f"{num1}/{num2 } is: {result:.5f}")
        except:
            logging.error(f"Error! num2 can not be 0 ")
    
    division(2,4)
    division(5, 6)
    division(7,0)
    division(8,10)
    division(3,0) 

    When you execute the above program, you will not see any output on the console becaue this time, we have specified a division.log file in the basicConfig() method, which will write all the logs in the file instead of printing them on the console. You can check your Python script directory there. You will see a new file by division.log . When you open the file, you will see the similar output

    2021-03-14 11:56:21,502 - DEBUG - dividing 2 by 4
    2021-03-14 11:56:21,502 - INFO - 2/4 is: 0.50000
    2021-03-14 11:56:21,502 - DEBUG - dividing 5 by 6
    2021-03-14 11:56:21,502 - INFO - 5/6 is: 0.83333
    2021-03-14 11:56:21,502 - DEBUG - dividing 7 by 0
    2021-03-14 11:56:21,502 - ERROR - Error! num2 can not be 0 
    2021-03-14 11:56:21,503 - DEBUG - dividing 8 by 10
    2021-03-14 11:56:21,503 - INFO - 8/10 is: 0.80000
    2021-03-14 11:56:21,503 - DEBUG - dividing 3 by 0
    2021-03-14 11:56:21,503 - ERROR - Error! num2 can not be 0

    Isn't it amazing to log out all the logs on a dedicated log file? All the large applications and software use logfiles to log out the detail of the program working.

    Conclusion

    Log files are very useful when you want to create a dedicated file that holds the history of the program's working. Although we can also use file handling to create a log file and save all the logs in that file, why use the traditional features when Python provides a dedicated module.

    In this tutorial, I have only scratched a few features of the Python logging module. The module provides many features and methods that be useful for your project I would recommend you to visit its official documentation if you want to know more about this module.

    People are also reading:

    Leave a Comment on this Post

    0 Comments