Replace logging with Loguru

We have a bunch of logging happening in our test popular automation framework and we were using standard Python logging module. We always wanted to make our debugging process simple and make logging look pleasant. Recently we came across the Python module Loguru which provides easier file logging with rotation / retention / compression and also provides good string formatting. Loguru is extremely simple, lightweight and at the same time very powerful and requires minimal setup code to start.
In this post, we are going to illustrate how we used Loguru in our Qxf2 framework

What is difference between standard logging and Loguru

Standard logging and Loguru provide almost the same functionality but Loguru reduces the pain of explicitly instantiating Logger and configuring the Handlers. The logger object is created and we can start using it to log messages. It acts like an interface that delivers the log messages to the configured handlers.

Loguru Implementation

In our framework, we replaced the standard logging with Loguru. Below sections details about the changes that we made for implementing Loguru.

Replace getLogger() function

Generally in standard logging mechanism, we call getLogger() which returns a logger with the specified name. With Loguru we need not explicitly do this, `from loguru import logger` is just enough. The logger is pre-configured and ready to use.

Replace standard Handler, Formatter, Filter

In Loguru, handlers are started using add(). Standard logging requires to create a Handler object and then call addHandler(). Loguru.logger automatically adds a handler when we import it. All the code for adding string and file handlers is not needed now in our framework. So we simply replaced below code

 log = logging.getLogger(test_module_name)
        if not os.path.exists(self.log_file_dir):
        if log_file_name is None:
            log_file_name = self.log_file_dir + os.sep + test_module_name + '.log'
            log_file_name = self.log_file_dir + os.sep + log_file_name


        rotation="30 days", filter=None, colorize=None, serialize=False, backtrace=True, enqueue=False, catch=True)

The add() function is used for adding a handler, setting up log formatting, filtering messages and setting levels.

Loguru provides few parameters like rotation/ retention/ compression to remove the older files or compress the files. Since we have a lot of logging messages in our framework, we have set a rotation parameter to 30 which specifies that the current logged file should be closed and a new one created after every 30 days.

Replace the styling of the messages

We have defined date and time format as per our requirement in our constructor logging class

 def __init__(self,log_file_name=None,level="DEBUG",format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module} | {message}"):
        "Constructor for the logging class"

Similarly, we have implemented string formatting’s using {} in the write() function for writing out the message.

 if level.lower()== 'debug': 
            logger.debug("{module} | {msg}",module=d['caller_func'],msg=msg)                
        elif level.lower()== 'info':
  "{module} | {msg}",module=d['caller_func'],msg=msg)

Here is the console log which shows a colorful output after adding different formatters.

Console output after adding formatter

Loguru provides many other features like structured logging, customize the levels, gives better data handling, sends email notifications using notifiers, automatically adds colors to the logs etc. Since Loguru comes with pre-configured, ready to use and is compatible with the standard logging, we could quickly implement it in our framework. We hope this post helps you in getting started with Loguru. Happy Logging!


1. Python logging made (stupidly) simple
2. Loguru Documentation

Leave a Reply

Your email address will not be published. Required fields are marked *