Python has a great integrated logging mechanism for developers. You don’t have to make complicated stuffs to activate logger and you can easily log to file or console with separating different kinds of log levels. In this writing, I will create a basic initialization method and use it to log my main program. More complicated implications are up to you.
First, I want to give some basic concepts of logger for python. Logger has a 5 different level in python. These are:
Every output place is controlled by handlers. For example, if you want to console output, you need to define console related handler. After that, you can handle logging level or logging format via that handler.
Now, I will give you a basic example code for logging. My file structure will be like below:
There is loggerinitializer.py file:
import logging import os.path def initialize_logger(output_dir): logger = logging.getLogger() logger.setLevel(logging.DEBUG) # create console handler and set level to info handler = logging.StreamHandler() handler.setLevel(logging.INFO) formatter = logging.Formatter("%(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) # create error file handler and set level to error handler = logging.FileHandler(os.path.join(output_dir, "error.log"),"w", encoding=None, delay="true") handler.setLevel(logging.ERROR) formatter = logging.Formatter("%(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) # create debug file handler and set level to debug handler = logging.FileHandler(os.path.join(output_dir, "all.log"),"w") handler.setLevel(logging.DEBUG) formatter = logging.Formatter("%(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler)
Line 5-6: Get main logger to add new specifications. Then set global log level to debug.
Line 9-13: In this area I add console logging mechanism to logger. In first line I get StreamHandler() and this means console for me. Then I said I only want output for INFO messages or higher level like errors or critical messages. For example Debug messages will not be printed out with this options. Then I give my own output format. There are a lot of options for this format and mine is very very simple. At the end, I add my console handler to my main logger.
Line 16-20: This area is nearly same as above except little differences. This time we get a FileHandler to write a file. In first parameter, we give the path for output file. Then we say we want to ‘write’ to file without any encoding specification. Last parameter puts some magic here. If no message is sent to this handler, no file will be created. The below lines are the same as above except that logger level is set to Error.
Line 23-27: In this area we create a new handler to log every message. We set level to debug, which is minimum, and let file be created every run.
After that, we can test this code with below code:
#!/usr/bin/env python3 from utils.loggerinitializer import * initialize_logger('/home/aykut/Documents/blog') logging.debug("debug message") logging.info("info message") logging.warning("warning message") logging.error("error message") logging.critical("critical message")
If we look at the outputs, we will see below: