{"id":12778,"date":"2020-05-20T08:08:22","date_gmt":"2020-05-20T12:08:22","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=12778"},"modified":"2020-05-20T08:09:55","modified_gmt":"2020-05-20T12:09:55","slug":"replace-python-standard-logging-with-loguru","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/replace-python-standard-logging-with-loguru\/","title":{"rendered":"Replace logging with Loguru"},"content":{"rendered":"<p>We have a bunch of logging happening in <a href=\"https:\/\/github.com\/qxf2\/qxf2-page-object-model\">our test popular automation framework<\/a> and we were using standard <a href=\"https:\/\/docs.python.org\/3\/library\/logging.html\">Python logging module<\/a>. We always wanted to make our debugging process simple and make logging look pleasant. Recently we came across the Python module <a href=\"https:\/\/github.com\/Delgan\/loguru\">Loguru<\/a> 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.<br \/>\nIn this post, we are going to illustrate how we used Loguru in our <a href=\"https:\/\/github.com\/qxf2\/qxf2-page-object-model\">Qxf2 framework<\/a> <\/p>\n<hr\/>\n<h3>What is difference between standard logging and Loguru<\/h3>\n<p>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.<\/p>\n<h3>Loguru Implementation<\/h3>\n<p>In our framework, we replaced the standard logging with Loguru. Below sections details about the changes that we made for implementing Loguru.<\/p>\n<h4>Replace getLogger() function<\/h4>\n<p>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. <\/p>\n<h4>Replace standard Handler, Formatter, Filter<\/h4>\n<p>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<\/p>\n<pre lang='python'>\r\n log = logging.getLogger(test_module_name)\r\n        self.reset_log(log)\r\n        self.set_log_level(log,level)\r\n        self.add_stream_handler(log,level,format)        \r\n        if not os.path.exists(self.log_file_dir):\r\n            os.makedirs(self.log_file_dir)\r\n        if log_file_name is None:\r\n            log_file_name = self.log_file_dir + os.sep + test_module_name + '.log'\r\n        else:\r\n            log_file_name = self.log_file_dir + os.sep + log_file_name\r\n        self.add_file_handler(log,level,format,log_file_name)\r\n<\/pre>\n<p>With<\/p>\n<pre lang='python'>\r\nlogger.add(log_file_name,level=level,format=format, \r\n        rotation=\"30 days\", filter=None, colorize=None, serialize=False, backtrace=True, enqueue=False, catch=True)\r\n<\/pre>\n<p>The add() function is used for adding a handler, setting up log formatting, filtering messages and setting levels.<\/p>\n<p>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. <\/p>\n<h4>Replace the styling of the messages<\/h4>\n<p>We have defined date and time format as per our requirement in our constructor logging class <\/p>\n<pre lang=\"python\">\r\n def __init__(self,log_file_name=None,level=\"DEBUG\",format=\"{time:YYYY-MM-DD HH:mm:ss} | {level} | {module} | {message}\"):\r\n        \"Constructor for the logging class\"\r\n        self.log_file_name=log_file_name<\/pre>\n<p>Similarly, we have implemented string formatting&#8217;s using {} in the write() function for writing out the message.<\/p>\n<pre lang='python'>\r\n if level.lower()== 'debug': \r\n            logger.debug(\"{module} | {msg}\",module=d['caller_func'],msg=msg)                \r\n        elif level.lower()== 'info':\r\n            logger.info(\"{module} | {msg}\",module=d['caller_func'],msg=msg)   \r\n<\/pre>\n<p>Here is the console log which shows a colorful output after adding different formatters.<\/p>\n<figure id=\"attachment_12832\" aria-describedby=\"caption-attachment-12832\" style=\"width: 1024px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/05\/log_console.JPG.jpg\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/05\/log_console.JPG-1024x549.jpg\" alt=\"\" width=\"1024\" height=\"549\" class=\"size-large wp-image-12832\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/05\/log_console.JPG-1024x549.jpg 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/05\/log_console.JPG-300x161.jpg 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/05\/log_console.JPG-768x412.jpg 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/05\/log_console.JPG.jpg 1154w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption id=\"caption-attachment-12832\" class=\"wp-caption-text\">Console output after adding formatter<\/figcaption><\/figure>\n<p>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!<\/p>\n<hr \/>\n<h3>References<\/h3>\n<p>1. <a href=\"https:\/\/github.com\/Delgan\/loguru\">Python logging made (stupidly) simple<\/a><br \/>\n2. <a href=\"https:\/\/loguru.readthedocs.io\/en\/stable\/api\/logger.html\">Loguru Documentation<\/a><\/p>\n<hr \/>\n","protected":false},"excerpt":{"rendered":"<p>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. [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[227,18],"tags":[],"class_list":["post-12778","post","type-post","status-publish","format-standard","hentry","category-logging","category-python"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12778","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=12778"}],"version-history":[{"count":28,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12778\/revisions"}],"predecessor-version":[{"id":12992,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12778\/revisions\/12992"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=12778"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=12778"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=12778"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}