{"id":1733,"date":"2024-06-13T21:53:18","date_gmt":"2024-06-13T16:23:18","guid":{"rendered":"https:\/\/geekpython.in\/?p=1733"},"modified":"2024-06-13T21:53:20","modified_gmt":"2024-06-13T16:23:20","slug":"logging-module-in-python","status":"publish","type":"post","link":"https:\/\/geekpython.in\/logging-module-in-python","title":{"rendered":"How to Use Logging Module in Python: Basic and Advanced Configuration"},"content":{"rendered":"\n<p>Logging debug or error messages is crucial for any application as it helps developers supervise and troubleshoot the application efficiently.<\/p>\n\n\n\n<p>Python provides a module named <code>logging<\/code> to log messages. These messages can be written to various destinations, including files, for better monitoring and debugging of programs.<\/p>\n\n\n\n<p>In this article, you&#8217;ll learn:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Logging a simple message using the logging module<\/strong><\/li>\n\n\n\n<li><strong>Severity level of the messages<\/strong><\/li>\n\n\n\n<li><strong>Configuring the<\/strong><code> <strong>logging<\/strong><\/code><strong> module to log<\/strong><code> <strong>INFO<\/strong><\/code><strong> and<\/strong><code> <strong>DEBUG<\/strong><\/code><strong> level messages and logging events to a file<\/strong><\/li>\n\n\n\n<li><strong>Logging the variable data<\/strong><\/li>\n\n\n\n<li><strong>Formatting the log messages using LogRecord attributes<\/strong><\/li>\n\n\n\n<li><strong>Advanced Configurations: Loggers, Handlers and Formatters<\/strong><\/li>\n\n\n\n<li><strong>Practical example<\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Logging Messages<\/h2>\n\n\n\n<p>Here&#8217;s an example of logging a simple message on the console using the <code>logging<\/code> module in Python.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:6 decode:true \" ># Imported logging module\nimport logging\n\nnum = 0\n# Logs a warning message\nlogging.warning(\"Entering Infinite Loop\")\nwhile True:\n    if num % 2 == 0:\n        print(num)\n    num += 1<\/pre><\/div>\n\n\n\n<p>The code above runs endlessly, thus when it runs, a warning message will be logged to alert the user.<\/p>\n\n\n\n<p>Here, <code>logging.warning()<\/code> has been used to log the warning message to the console. The <code>warning<\/code> here is the severity level of the message.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:sh decode:true \" >WARNING:root:Entering Infinite Loop\n0\n2\n4\n.\n.\n.<\/pre><\/div>\n\n\n\n<p>As you can see, the output begins by logging the warning message <strong>&#8220;Entering Infinite Loop&#8221;<\/strong> in the pattern <code>WARNING:root:&lt;message&gt;<\/code>, indicating the severity level and name assigned by the logger respectively.<\/p>\n\n\n\n<p>Similar to this, the <code>logging<\/code> module offers several levels to show the events&#8217; severity.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" ># Imported logging module\nimport logging\n\nlogging.info(\"Used to log info message\")\nlogging.debug(\"Used to log debug message\")\nlogging.warning(\"Used to log warning message\")\nlogging.error(\"Used to log error message\")\nlogging.critical(\"Used to log critical message\")<\/pre><\/div>\n\n\n\n<p>There are 5 different levels to log messages of different severity levels.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>INFO<\/strong><\/li>\n\n\n\n<li><strong>DEBUG<\/strong><\/li>\n\n\n\n<li><strong>WARNING<\/strong><\/li>\n\n\n\n<li><strong>ERROR<\/strong><\/li>\n\n\n\n<li><strong>CRITICAL<\/strong><\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:sh decode:true \" >WARNING:root:Used to log warning message\nERROR:root:Used to log error message\nCRITICAL:root:Used to log critical message<\/pre><\/div>\n\n\n\n<p>You can observe that the output is missing the first two messages. <strong>Why is it so?<\/strong> The messages with a severity level of <code>WARNING<\/code> and above are logged by the <code>logging<\/code> module.<\/p>\n\n\n\n<p>You can log <code>INFO<\/code> and <code>DEBUG<\/code> messages by applying some configurations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring Logging Module<\/h2>\n\n\n\n<p>The <code>logging<\/code> module can be configured to unleash more power to let you do more stuff when logging events.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Configuration<\/h3>\n\n\n\n<p>The <code>logging<\/code> module includes a function called <code>basicConfig()<\/code> that helps in configuring the logging system. Here&#8217;s an example of configuring <code>logging<\/code> module to log <code>INFO<\/code> level message.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:4-5 decode:true \" >import logging\n\n# Configuring logging\nlogging.basicConfig(level=logging.INFO)\nlogging.info(\"This info will be printed\")<\/pre><\/div>\n\n\n\n<p>The <code>logging<\/code> module is configured in the code above to log a <code>INFO<\/code> message by passing the keyword argument <code>level<\/code> to the <code>basicConfig()<\/code> function and setting it to <code>logging.INFO<\/code>.<\/p>\n\n\n\n<p>When you run the above code, the severity level <code>INFO<\/code> message will now be printed.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:sh decode:true \" >INFO:root:This info will be printed<\/pre><\/div>\n\n\n\n<p>Similarly, you can log <code>DEBUG<\/code> messages by setting the <code>level<\/code> argument to the value <code>logging.DEBUG<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:4-5 decode:true \" >import logging\n\n# Configuring logging to log DEBUG msg\nlogging.basicConfig(level=logging.DEBUG)\nlogging.debug(\"This is a DEBUG message\")\n\n--------------------\nDEBUG:root:This is a DEBUG message<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Logging Event to a File<\/h3>\n\n\n\n<p>The <code>basicConfig()<\/code> function accepts a keyword argument called <code>filename<\/code> to specify the file in which the event will be logged.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:4 decode:true \" >import logging\n\n# Logging to a file\nlogging.basicConfig(filename='debug.log', level=logging.DEBUG)\nlogging.debug(\"This is a DEBUG message\")<\/pre><\/div>\n\n\n\n<p>The message will be logged into the <code>debug.log<\/code> file and it will be the same as the previous output but in the file instead of the console.<\/p>\n\n\n\n<p>By default, the mode of the file is set to append (<code>a<\/code>) mode and you can change this by specifying the <code>filemode<\/code> parameter. Additionally, you can use the <code>encoding<\/code> parameter to specify the file&#8217;s encoding.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:4-7 decode:true \" >import logging\n\n# Logging to a file\nlogging.basicConfig(filename='debug_new.log',\n                    filemode='w',\n                    encoding='utf-8',\n                    level=logging.DEBUG)\nlogging.debug(\"Debugging starts from here.\")<\/pre><\/div>\n\n\n\n<p>In this example, the file is set to write (<code>filemode='w'<\/code>) mode and encoding is set to <code>'utf-8'<\/code>. This time the message will be logged into the <code>debug_new.log<\/code> file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Log Variable Data?<\/h2>\n\n\n\n<p>Logging variable data is similar to formatting a string using the <code>%<\/code> operator. This helps when you want to include dynamic data in logged messages.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:3 decode:true \" >import logging\n\n# Logging variable data\nlogging.error(\"%s: Not found - Status: %s\", 404, \"Fail\")<\/pre><\/div>\n\n\n\n<p>In this code, two placeholders (<code>%s<\/code>) are present in the string that will help Python interpolate the string with the specified values i.e., <code>404<\/code> and <code>'Fail'<\/code>, and they will be placed in the same position as they appear.<\/p>\n\n\n\n<p>When you run the code, you&#8217;ll get the following output.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:sh decode:true \" >ERROR:root:404: Not found - Status: Fail<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Formatting the Logged Messages<\/h2>\n\n\n\n<p>You now know how to log variable data; in this section, you&#8217;ll utilize it to format the logged messages.<\/p>\n\n\n\n<p>You can choose the format of your logged message to be displayed in the console or a file.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:3 decode:true \" >import logging\n\nlogging.basicConfig(format='%(levelname)s - %(message)s')\nlogging.warning(\"Things are getting worse.\")\n\n--------------------\nWARNING - Things are getting worse.<\/pre><\/div>\n\n\n\n<p>As you can see, the message is logged with the formatting that the <code>format<\/code> argument set. The severity (<code>levelname<\/code>) is shown first, then the event&#8217;s description (<code>message<\/code>).<\/p>\n\n\n\n<p>You may be wondering now where the <code>message<\/code> and <code>levelname<\/code> came from. Well, these are the attributes specified by the <a href=\"https:\/\/docs.python.org\/3\/library\/logging.html#logrecord-attributes\" target=\"_blank\" rel=\"noreferrer noopener\">LogRecord<\/a>. Similarly, LogRecord has more attributes.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:4 decode:true \" >import logging\n\nlogging.basicConfig(\n    format='%(levelname)s: %(message)s - %(asctime)s', \n    level=logging.DEBUG\n)\nlogging.debug(\"Debugging started at\")<\/pre><\/div>\n\n\n\n<p>Now, this time a new attribute <code>asctime<\/code> is added to the message that logs the date and time of the event. The output looks like the following.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:sh decode:true \" >DEBUG: Debugging started at - 2024-06-12 16:37:55,996<\/pre><\/div>\n\n\n\n<p>You can take more control of formatting the date and time of the event by passing the <code>datefmt<\/code> argument in the <code>basicConfig()<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:5 decode:true \" >import logging\n\nlogging.basicConfig(\n    format='%(levelname)s: %(message)s - %(asctime)s',\n    datefmt='%d\/%m\/%Y %I:%M:%S %p', \n    level=logging.DEBUG\n)\nlogging.debug(\"Debugging started at\")\n\n--------------------\nDEBUG: Debugging started at - 12\/06\/2024 05:55:38 PM<\/pre><\/div>\n\n\n\n<p>The date and time looks more readable now due to the string (<code>'%d\/%m\/%Y %I:%M:%S %p'<\/code>) set by the <code>datefmt<\/code> argument. You can experiment with the characters within the string just like you would do in the <a href=\"https:\/\/docs.python.org\/3\/library\/time.html#time.strftime\" target=\"_blank\" rel=\"noreferrer noopener\"><code>time.strftime()<\/code><\/a><strong>.<\/strong> Here&#8217;s an example.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:5 decode:true \" >import logging\n\nlogging.basicConfig(\n    format='%(levelname)s: %(message)s - %(asctime)s',\n    datefmt='%d %b %Y %a %I:%M:%S %p', \n    level=logging.DEBUG\n)\nlogging.debug(\"Debugging started at\")\n\n--------------------\nDEBUG: Debugging started at - 12 Jun 2024 Wed 06:08:20 PM<\/pre><\/div>\n\n\n\n<p>You can add some more attributes such as file name, module name, process ID, name of the logger, and much more.<\/p>\n\n\n\n<p>So far you&#8217;ve learned to log messages at the basic level. In the next section, you&#8217;ll learn to log messages at an advanced level such as configuring your logger, sending the log messages over multiple destinations, and much more.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Logging &#8211; Advanced Configurations<\/h2>\n\n\n\n<p>In this section, you&#8217;ll use classes and functions to log messages. The commonly used classes in the <code>logging<\/code> module are as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Logger<\/strong> &#8211; Used to create logger objects so that logging can be performed by calling different methods on its objects.<\/li>\n\n\n\n<li><strong>Handler<\/strong> &#8211; Used to send log messages to appropriate destinations such as into the file, email, HTTP server, etc.<\/li>\n\n\n\n<li><strong>Formatter<\/strong> &#8211; Used to set the format of the log records in the final output.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Creating Logger Object<\/h3>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:4 decode:true \" >import logging\n\n# Create a logger\nlogger = logging.getLogger(\"custom_logger\")\nlogger.warning(\"Warning... Warning...\")<\/pre><\/div>\n\n\n\n<p>In this example, a custom logger named <code>custom_logger<\/code> is created using <code>logging.getLogger()<\/code>. When you run this code, you&#8217;ll get the following output.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:sh decode:true \" >Warning... Warning...<\/pre><\/div>\n\n\n\n<p>This is a simple message without the severity level and logger name even though the name of the logger was specified. This is because the custom logger can&#8217;t be configured using <code>basicConfig()<\/code>. To format this output, you need to use <strong>Handlers<\/strong> and <strong>Formatters<\/strong>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>An important note:<\/p>\n\n\n\n<p>It is a good practice to name your logger based on module like the following.<\/p>\n\n\n\n<p><code>logger = logging.getLogger(__name__)<\/code><\/p>\n\n\n\n<p>This will keep track of your module\/package hierarchy. It means if you are using it in same module, the logger name will be <code>__main__<\/code> and if you import this module into another module, then the logger name will the <code>module_name<\/code>, the name of the module in which it is defined.<\/p>\n<\/blockquote>\n\n\n\n<p>The logger object doesn&#8217;t log messages of severity level <code>DEBUG<\/code> and <code>INFO<\/code>. To log <code>DEBUG<\/code> or <code>INFO<\/code> level messages using the custom logger, you need to create a handler.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating Handler<\/h3>\n\n\n\n<p>Handler objects are responsible for logging records to the specified destinations. There are several handler types such as <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/docs.python.org\/3\/library\/logging.handlers.html#logging.StreamHandler\"><code>StreamHandler<\/code><\/a>, <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/docs.python.org\/3\/library\/logging.handlers.html#logging.FileHandler\"><code>FileHandler<\/code><\/a>, <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/docs.python.org\/3\/library\/logging.handlers.html#logging.handlers.HTTPHandler\"><code>HTTPHandler<\/code><\/a>, <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/docs.python.org\/3\/library\/logging.handlers.html#logging.handlers.SMTPHandler\"><code>SMTPHandler<\/code><\/a> and <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/docs.python.org\/3\/howto\/logging.html#useful-handlers\">more<\/a>.<\/p>\n\n\n\n<p>The <code>addHandler()<\/code> method is used to add one or more handlers to the logger object. You need to add the individual handler to log messages based on categories to different destinations.<\/p>\n\n\n\n<p>After creating a logger object in the previous section, the next step is to create the handler.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:9-12,14-16 decode:true \" ># adv_logging.py\n\nimport logging\n\n# Create a logger\nlogger = logging.getLogger(__name__)\nlogger.setLevel(logging.INFO)  # Set the logger's level\n\n# Creating Handlers\n# Console handler\ncs_handler = logging.StreamHandler()\ncs_handler.setLevel(logging.INFO)\n\n# File handler\nfl_handler = logging.FileHandler(\"info.log\")\nfl_handler.setLevel(logging.ERROR)<\/pre><\/div>\n\n\n\n<p>In this code, some modifications have been done to the logger object such as the logger&#8217;s name changed and the logger&#8217;s level has been set to <code>INFO<\/code>.<\/p>\n\n\n\n<p>Two handlers have been created <code>cs_handler<\/code> and <code>fl_handler<\/code>. The first handler (<code>cs_handler<\/code>) is responsible for sending messages in the console and its level is set to <code>INFO<\/code>. The second handler (<code>fl_handler<\/code>) sends the messages to the file name <code>info.log<\/code> which is set to <code>ERROR<\/code> level.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating Formatters<\/h3>\n\n\n\n<p>Formatters are responsible for applying the formatting of the developer&#8217;s choice to the final output.<\/p>\n\n\n\n<p>It is similar to the formatting you&#8217;ve learned while setting up the basic configurations of the messages using <code>basicConfig()<\/code>. But here, you need to use a <code>Formatter<\/code> class of the <code>logging<\/code> module.<\/p>\n\n\n\n<p>Here&#8217;s the extension of the previous code.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >...\n\n# Creating Formatters\n# Formatter for console\ncs_formatter = logging.Formatter(\n    '%(asctime)s: %(name)s - %(levelname)s: %(message)s',\n    datefmt='%d %b %Y %a %I:%M:%S %p'\n)\n# Setting formatter to handler\ncs_handler.setFormatter(cs_formatter)\n\n# Formatter for file\nfl_formatter = logging.Formatter(\n    '%(asctime)s: %(name)s - %(levelname)s: %(message)s',\n    datefmt='%d %b %Y %a %I:%M:%S %p'\n)\n# Setting formatter to handler\nfl_handler.setFormatter(fl_formatter)<\/pre><\/div>\n\n\n\n<p>The formatters <code>cs_formatter<\/code> and <code>fl_formatter<\/code> have been created. The formatting style of both formatters is identical, and <code>setFormatter()<\/code> has been used to assign each formatter to its corresponding handler.<\/p>\n\n\n\n<p>To log messages with applied configurations, the final step is to add these handlers (<code>cs_handler<\/code> and <code>fl_handler<\/code>) to the logger.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >...\n\n# Adding handler to logger\nlogger.addHandler(cs_handler)\nlogger.addHandler(fl_handler)<\/pre><\/div>\n\n\n\n<p>Now add messages to be logged.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >...\n\nlogger.info(\"Process started...\")\nlogger.warning(\"Warning... Warning...\")\nlogger.error(\"Unusual activity detected...\")\nlogger.critical(\"System security compromised...\")<\/pre><\/div>\n\n\n\n<p><strong>Output<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:sh decode:true \" >13 Jun 2024 Thu 03:55:24 PM: __main__ - INFO: Process started...\n13 Jun 2024 Thu 03:55:24 PM: __main__ - WARNING: Warning... Warning...\n13 Jun 2024 Thu 03:55:24 PM: __main__ - ERROR: Unusual activity detected...\n13 Jun 2024 Thu 03:55:24 PM: __main__ - CRITICAL: System security compromised...<\/pre><\/div>\n\n\n\n<p>Here, the <code>logging.info()<\/code>, <code>logging.warning()<\/code>, <code>logging.error()<\/code>, <code>logging.critical()<\/code> passed the information to the handlers (<code>cs_haldler<\/code> and <code>fl_handler<\/code>).<\/p>\n\n\n\n<p>Since the logger&#8217;s level is set to <code>INFO<\/code> and <code>cs_handler<\/code> is a <code>StreamHandler<\/code> set to <code>INFO<\/code> level printed the messages with specified formatting of <code>INFO<\/code> level and above in the console.<\/p>\n\n\n\n<p>The <code>fl_handler<\/code> is a <code>FileHandler<\/code> which is set to <code>ERROR<\/code> level will log the messages in the <code>info.log<\/code> file of the level <code>ERROR<\/code> and above.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tex decode:true \" >13 Jun 2024 Thu 03:55:24 PM: __main__ - ERROR: Unusual activity detected...\n13 Jun 2024 Thu 03:55:24 PM: __main__ - CRITICAL: System security compromised...<\/pre><\/div>\n\n\n\n<p>You can see that the name of the logger is logged as <code>__main__<\/code> which means the source file is executed directly. If you import this module to another file and then run it, the name of the logger will change.<\/p>\n\n\n\n<p>Create a new Python file, in this case, <code>sample_log.py<\/code>. Import the source file into it, and then run the file.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:2 decode:true \" ># sample_log.py\nimport adv_logging<\/pre><\/div>\n\n\n\n<p>When you run this file, your output will look like the following.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:sh decode:true \" >13 Jun 2024 Thu 03:58:12 PM: adv_logging - INFO: Process started...\n13 Jun 2024 Thu 03:58:12 PM: adv_logging - WARNING: Warning... Warning...\n13 Jun 2024 Thu 03:58:12 PM: adv_logging - ERROR: Unusual activity detected...\n13 Jun 2024 Thu 03:58:12 PM: adv_logging - CRITICAL: System security compromised...<\/pre><\/div>\n\n\n\n<p>The <code>info.log<\/code> file will look like the following.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tex mark:3-4 decode:true \" >13 Jun 2024 Thu 03:55:24 PM: __main__ - ERROR: Unusual activity detected...\n13 Jun 2024 Thu 03:55:24 PM: __main__ - CRITICAL: System security compromised...\n13 Jun 2024 Thu 03:58:12 PM: adv_logging - ERROR: Unusual activity detected...\n13 Jun 2024 Thu 03:58:12 PM: adv_logging - CRITICAL: System security compromised...<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Practical Example<\/h2>\n\n\n\n<p>You&#8217;ve learned to create the logger and handlers with specified formatting. Now you can create a template for logging the messages and include it in your project code to log messages dynamically.<\/p>\n\n\n\n<p>Here&#8217;s a practical example of creating a logger with advanced configurations and then including it in the main script to log messages in a file.<\/p>\n\n\n\n<p>First, create a Python file, in this case, <code>log_temp.py<\/code>. This file holds a template for logging a message.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:22-30 decode:true \" ># log_temp.py\nimport logging\n\n# Create a logger\nlogger = logging.getLogger(__name__)\nlogger.setLevel(logging.INFO)\n\n# File handler\nfl_handler = logging.FileHandler(\"log_file.log\")\nfl_handler.setLevel(logging.INFO)\n\n# Formatter for file\nfl_formatter = logging.Formatter(\n    '%(name)s - %(levelname)s: %(message)s'\n)\n# Setting formatter to handler\nfl_handler.setFormatter(fl_formatter)\n\n# Adding handler to logger\nlogger.addHandler(fl_handler)\n\n# Function to log INFO level msg\ndef info_msg(msg):\n    logger.info(msg)\n# Function to log WARNING level msg\ndef warning_msg(msg):\n    logger.warning(msg)\n# Function to log ERROR level msg\ndef error_msg(msg):\n    logger.error(msg)<\/pre><\/div>\n\n\n\n<p>This code is pretty much the same as you saw in the previous sections but this time three functions are added: <code>info_msg()<\/code>, <code>warning_msg()<\/code>, and <code>error_msg()<\/code>.<\/p>\n\n\n\n<p>These functions log <code>INFO<\/code>, <code>WARNING<\/code>, and <code>ERROR<\/code> level messages. The messages will be provided by the developer.<\/p>\n\n\n\n<p>This template uses <code>FileHandler<\/code> to log messages in a file of level <code>INFO<\/code> and above.<\/p>\n\n\n\n<p>Now, create another Python file, in this case, <code>script.py<\/code>, and dump the following code or write your own Python program.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:7,15,18 decode:true \" ># Imported template\nimport log_temp\n\ntry:\n    num = 0\n    # Logs a warning message\n    log_temp.warning_msg(\"Entering Infinite Loop\")\n    while True:\n        if num % 2 == 0:\n            print(num)\n        num += 1\n\nexcept KeyboardInterrupt:\n    # Logs an error message\n    log_temp.error_msg(\"Program Interrupted\")\n\n# Logs an info\nlog_temp.info_msg(\"Program continued\")\nprint(\"Exited infinite loop\")<\/pre><\/div>\n\n\n\n<p>This code runs infinitely and when it runs, it logs a warning message and if the loop is interrupted, it logs an error message followed by the info that the program continued after exiting the loop.<\/p>\n\n\n\n<p>When you run the <code>script.py<\/code> file, you&#8217;ll get these details logged into the <code>log_file.log<\/code> file.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tex decode:true \" >log_temp - WARNING: Entering Infinite Loop\nlog_temp - ERROR: Program Interrupted\nlog_temp - INFO: Program continued<\/pre><\/div>\n\n\n\n<p>When the code starts executing, a warning message is logged, and then when the program gets interrupted, an error message is logged followed by the info message that provides info that the program continued after interruption.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Keeping log records of the applications can help better supervise and troubleshoot them. Python provides a standard library named logging for recording log messages for your applications.<\/p>\n\n\n\n<p>You can apply basic and advanced configurations to the logging module to unleash more power. You can log messages in the console as well as to various destinations like inside a file, email, HTTP connection, etc.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83c\udfc6<strong>Other articles you might be interested in if you liked this one<\/strong><\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/type-hinting-in-python\">Type hints in Python &#8211; Callable objects, Return values, and more<\/a>?<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/positional-and-keyword-arguments-in-python\">Best Practices: Positional and Keyword Arguments in Python<\/a><\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/yield-keyword-in-python\">Yield Keyword in Python with Examples<\/a>?<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/build-websocket-server-and-client-using-python\">Create a WebSocket Server and Client in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/mysql-database-in-python\">Create and Interact with MySQL Database in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/understanding-the-use-of-global-keyword-in-python\">Understanding the use of global keyword in Python<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>That&#8217;s all for now<\/strong><\/p>\n\n\n\n<p><strong>Keep Coding\u270c\u270c<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Logging debug or error messages is crucial for any application as it helps developers supervise and troubleshoot the application efficiently. Python provides a module named logging to log messages. These messages can be written to various destinations, including files, for better monitoring and debugging of programs. In this article, you&#8217;ll learn: Logging Messages Here&#8217;s an [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1734,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[42,2],"tags":[79,43,31],"class_list":["post-1733","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modules","category-python","tag-logging","tag-modules","tag-python3","entry","has-media"],"_links":{"self":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1733","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/comments?post=1733"}],"version-history":[{"count":2,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1733\/revisions"}],"predecessor-version":[{"id":1736,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1733\/revisions\/1736"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media\/1734"}],"wp:attachment":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media?parent=1733"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/categories?post=1733"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/tags?post=1733"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}