Python: Why You Should Start Using Logging Instead of Print()

June 29, 2021

Logging is a built-in library within Python, which offers capabilities to log and store different levels of information throughout a program, helping developers to monitor, investigate and diagnose their program effectively. However, many data professionals resort to the print() to get information from the program, as typing a function is just easier and it doesn’t cost time to set up. For a simple program, this might be fine, however once the system becomes more complex and the program starts running outside of the development environment, the Logging library will certainly save the developer time and effort. Today, we would like to explore several key features/benefits of using Logging.

Registering Different Levels of Information for Effective Monitoring:
There are five levels of information that you can register to monitor a program. Each of them indicates a different level of importance with a numeric value attached to it.

Source: https://docs.python.org/3.8/library/logging.html

We have included a code sample for the logging configuration of a prospective project. As you can see, we have specified a log level of “DEBUG” for both the StreamHandler and the FileHandler. A StreamHandler logs messages and prints to the console and a FileHandler logs messages and saves into a .log file. In our example, the log messages at DEBUG level or above will be both printed and saved. We have also specified formats for both types of log messages with BASE_FORMAT and FILE_FORMAT.

#logging_config.py

LOGGING_CONFIG = {
    "version": 1,
    "formatters": {
        "BASE_FORMAT": {
            'format': '[%(name)s][%(levelname)-6s]%(message)s',
        },
        'FILE_FORMAT':{
            'format': '[%(asctime)s] [%(name)s][%(levelname)-6s] %(message)s',
        },
    },
    "handlers": {
        "console" : {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "BASE_FORMAT"
        },
        "file" : {
            "class" : "logging.FileHandler",
            "filename": "pipeline_{}.log".format(datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S")),
            "level" : "DEBUG",
            "formatter" : "FILE_FORMAT",
        }
    },
    "root" : {
        "level" : "DEBUG",
        "handlers" : ["console", "file"]
    }
}

Storing Logs for Debugging and Archiving Purposes:
With a FileHandler configured in the LOGGING_CONFIG dictionary specified above, we are able to save and store a log every time we run through our program. In addition, we named the log with a timestamp so that we can easily trace back the log based on the time that it was recorded. Below, please see a snapshot of the logs that we have received from running a system.

Distributing Logs as Notification:
The logging module also offers a class called SMTPHandler, which can help the developers to be notified of logging messages via emails. Upon reading the logging messages, the developer can decide whether to jump on the project depending on the log message.

https://docs.python.org/3/library/logging.handlers.html

All these features and benefits wouldn’t have been possible with a simple print() and these features will certainly make your project more robust and effective in the production environment.