Print Logs in Python
Logging is used to track events when some software runs. An event is a descriptive message which can optionally contain variable data.
Logging Functions
Logging provides a set of easy to use functions for simple logging usage in Python. These functions are debug(), info(), warning(), error(), and critical(). These functions are named after the level of severity of the events that they are used for tracking. The usage of these functions are described below:
Level | Usage |
DEBUG | To track detailed information when diagnosing problems. |
INFO | To confirm things are working as expected. |
WARNING | To indicate that everything is working as expected but something unexpected happened and may cause problems in the future. For Example - Low disk space. |
ERROR | To indicate some serious problem occured due to which some functions were failed to run. |
CRITICAL | To indicate a serious problem due to which the program itself may not continue to work. |
A Simple Logging
A simple logging example:
import logging;
logging.warning("File size too big")
logging.info("Started to run!")
If you add the above lines to your code and run it, you will see:
The INFO message is not printed because the default level is WARNING. The logging message includes the severity level of the log and the description of the event.
Logging to a File
For most applications, log events are usually written to a file, lets look at it next:
import logging;
logging.basicConfig(filename='example.log', level=logging.DEBUG)
logging.warning("File size too big")
logging.info("Started to run!")
logging.error("Something went wrong!")
logging.debug("Debugging a problem")
logging.critical("Something serious is causing the application to stop!")
The call to basicConfig should be made before any calls to info(), debug(), error(), etc.
If the above script is run several times, the log messages from every successive runs are appended to the file example.log. We can also discard the messages from earlier runs by specifying the filemode argument as shown in the example below:
logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG)
Logging Variable Data
Use a format string for the event log message and append the variable data as arguments.
Example
import logging;
logging.warning("%s file size is % which is too big!", 'text.')
If you run the above script, you'll see:
Change the Format of Log Messages
Use the format argument to change the format of displaying log messages.
Example
import logging;
logging.basicConfig(format='%(levelname)s: %(message)s')
logging.warning("Changing format of log messages")
If you run the above script, you'll see:
Show Datetime in Log Messages
Use the %(asctime)s in format argument to display datetime of an event in log messages. You can also use datefmt argument to format datetime.
Example
import logging
logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning("Displaying date in log messages")
If you run the above script, you'll see:
Advanced Logging
The logging library takes a modular approach and provides the components as follows:
- Loggers — class whose objects helps to call the logging functions directly in the application code.
- Handlers — sends log records created by loggers to the appropriate destination.
- Filters — helps to filter log records.
- Formatters — helps to format the log messages.
Rotating disk log files in Python
To rotate disk log files in Python, you can use RotatingFileHandler class, located in the logging.handlers module.
The use of maxBytes and backupCount values in RotatingFileHandler allows the file to rollover at a predetermined size. Rollover never occurs if the value of maxBytes and backupCount is zero. When the current log file size is nearly the maxBytes value in length, the rollover occurs. The value of backupCount argument determines the number of files, the system will create to save old log files by appending the extensions .1, .2, .3, etc., to the filename. For example, with a backupCount of 6 and a base file name of example.log, you would get example.log, example.log.1, example.log.2, example.log.3, example.log.4, example.log.5, and example.log.6. The log messages being written to is always example.log file. When the file size is nearly the maxBytes, it is closed and renamed to example.log.1 and if there is example.log.1 and example.log.2, then they are renamed to example.log.3 and example.log.4.
Here is an example of rotating disk log files in Python:
Example
my_logger.py
import logging
from logging.handlers import RotatingFileHandler
import os
import sys
from pathlib import Path
import datetime
def Logger(log_filename):
if not log_filename:
log_filename = str(Path(__file__).parent.parent) + "/logs/default.log"
try:
# Create logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# Create handlers
str_handler = logging.StreamHandler()
file_handler = logging.handlers.RotatingFileHandler(
log_filename, mode='a', maxBytes=100000000, backupCount=4)
str_handler.setLevel(logging.INFO)
file_handler.setLevel(logging.INFO)
# Create formatters and add it to handlers
str_format = logging.Formatter(
'%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
file_format = logging.Formatter(
'%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
str_handler.setFormatter(str_format)
file_handler.setFormatter(file_format)
# Add handlers to the logger
logger.addHandler(str_handler)
logger.addHandler(file_handler)
return logger
except Exception:
err = sys.exc_info()
print("Error : %s" % (err))
test.py
from my_logger import Logger
def my_first_function(logger):
logger.info("Running first function")
logger.error("Error in first function")
def my_second_function(logger):
logger.info("Running second function")
logger.error("Error in second function")
logger = Logger("example.log")
my_first_function(logger)
my_second_function(logger)
If you run test.py file, you should see this in example.log:
2021-04-15 13:02:01,148 - tezt.py - ERROR - Error in first function
2021-04-15 13:02:01,148 - tezt.py - INFO - Running second function
2021-04-15 13:02:01,148 - tezt.py - ERROR - Error inn second function