{"id":2092,"date":"2018-06-04T16:45:51","date_gmt":"2018-06-04T16:45:51","guid":{"rendered":"http:\/\/bluegalaxy.info\/codewalk\/?p=2092"},"modified":"2019-07-02T14:02:41","modified_gmt":"2019-07-02T19:02:41","slug":"python-use-logging-module","status":"publish","type":"post","link":"https:\/\/bluegalaxy.info\/codewalk\/2018\/06\/04\/python-use-logging-module\/","title":{"rendered":"Python: How to use the logging module"},"content":{"rendered":"<p>Sending print statements to the console is very common in Python coding. It is simply a matter of using the key word print, followed by what you want printed to the screen. For example:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># variables\nyear = '2015'\nxldate = 41000\npvid_list = [\"19615056\", \"15612770\", \"15612771\"]\n\n# print a raw string\nprint \"Print this string...\"\n\n# print a raw string and variable containing a string\nprint \"The year is\", year\n\n# print three variables, containing a string, number, and list\nprint year, xldate, pvid_list\n<\/pre>\n<p>Which yields:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">Print this string...\nThe year is 2015\n2015 41000 ['19615056', '15612770', '15612771']<\/pre>\n<p>Now lets say you want to not only send print statements to the console, but you also want those print statements to be captured in a log. This can be ideal if you have a large script with many functions and you want to have a saved record that can be examined for each run of the script.<\/p>\n<p>Python has a logging module that makes this possible. To use this module, you will need to include an \u2018import logging\u2019 statement at the top of your script. For the code example I will share for this tutorial, you will also need to import the \u2018inspect\u2019 module.<\/p>\n<p>The code I am going to share includes a function called log_handlers that creates two handlers for the logging module.<\/p>\n<ul>\n<li><code>StreamHandler()<\/code> \u2013 controls what is printed to the console<\/li>\n<li><code>FileHandler()<\/code> \u2013 controls what is printed to the log file<\/li>\n<\/ul>\n<p>Whenever you start your script, you will need to access this function to initialize the handlers. For example, in main():<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">global logger\nlogger = log_handlers(logging.INFO, logging.INFO)<\/pre>\n<p>Before your script ends, you should shut the logging module down. For example, I used this as the last line of code in main():<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">logging.shutdown()<\/pre>\n<p>In order to use the logger created previously, you will need to use the following code in place of a print statement. Where you would previously print a string to the console like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># print a raw string\nprint \"Print this string...\"<\/pre>\n<p>You can now print the same string to the console AND the log file by using <code>logger.info()<\/code> with the string in parenthesis, like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># print a raw string to both the console and the log\nlogger.info('Print this string...')<\/pre>\n<p>Where you would previously print a string and variable to the console like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># print a raw string and variable containing a string\nprint \"The year is\", year\n<\/pre>\n<p>You can now print the same string and variable to the console AND the log file using logger.info like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">logger.info(\"The year is: %s\" % (year))<\/pre>\n<p>Notice that the variable name year is in its own parenthesis. The string value stored in the variable will be substituted into the <code>%s<\/code> in the double quotes. This will yield the same results as the print statement.<\/p>\n<p>Where you would previously print three variables, containing a string, number, and list like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># print three variables, containing a string, number, and list\nprint year, xldate, pvid_list<\/pre>\n<p>You can now print the same three variables to the console AND the log file using <code>logger.info<\/code> like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">logger.info(\"%s %s %s\" % (year, xldate, pvid_list))<\/pre>\n<p>Notice that all three variable names are in the parenthesis, separated by commas. Each of these point to their own <code>%s<\/code> placeholder in the string portion (in order). The first variable points to the first <code>%s<\/code>, the second variable points to the second %s, etc..<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2097\" src=\"http:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2018\/07\/three-subs.png\" alt=\"\" width=\"605\" height=\"86\" srcset=\"https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2018\/07\/three-subs.png 605w, https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2018\/07\/three-subs-300x43.png 300w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/p>\n<p>The output is the same as the print statement:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">2015 41000 ['19615056', '15612770', '15612771']<\/pre>\n<p>All three lines also went to the log file, in this case called \u201cOutput_log_020615_1129.txt\u201d:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2099\" src=\"http:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2018\/07\/logging-out.png\" alt=\"\" width=\"434\" height=\"73\" srcset=\"https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2018\/07\/logging-out.png 434w, https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2018\/07\/logging-out-300x50.png 300w\" sizes=\"auto, (max-width: 434px) 100vw, 434px\" \/><\/p>\n<p>The log file can be named anything you like. It can have the extension <code>.txt<\/code> or <code>.log<\/code>. In this example case, I used today\u2019s date and timestamp as part of the name of the log. \u201cOutput_log_\u201d + MMDDYY + \u201c_\u201d + HHMM + \u201c.txt\u201d.<\/p>\n<p>Here is the log_handlers function that makes this work:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">def log_handlers(file_level, console_level = None):\n    function_name = inspect.stack()[1][3]\n    logger = logging.getLogger(function_name)\n    logger.setLevel(logging.DEBUG) #By default, DEBUG logs all messages\n\n    #log_name = 'Output_log_' + getDate() + '.log'\n    log_name = 'Output_log_' + getDate() + '_' + getTime() + '.txt'\n\n    # Clear out existing handlers to avoid duplicated data\n    logger.handlers = []\n\n    if not logger.handlers:\n        if console_level != None:\n            ch = logging.StreamHandler() #StreamHandler logs to console\n            ch.setLevel(console_level)\n            ch_format = logging.Formatter('%(message)s')\n            ch.setFormatter(ch_format)\n            logger.addHandler(ch)\n\n        #FileHandler logs to log file. mode='w' is optional for overwrite\n        fh = logging.FileHandler(log_name.format(function_name), mode='w')\n        fh.setLevel(file_level)\n        fh_format = logging.Formatter('%(message)s')\n        fh.setFormatter(fh_format)\n        logger.addHandler(fh)\n\n    return logger<\/pre>\n<p>The <code>mode=\u2018w\u2019<\/code> in the Filehandler setup is optional and will cause the log handler to overwrite the existing log file with each subsequent execution of your script. This can be left off and the default setting would be \u201cappend\u201d.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">fh = logging.FileHandler(log_name.format(function_name), mode='w')<\/pre>\n<p>For example:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">fh = logging.FileHandler(log_name.format(function_name))<\/pre>\n<p>While this tutorial covers just a single use case, there are many other things that can be done with the logging module. For more details, visit the following website resources:<br \/>\n<a href=\"https:\/\/docs.python.org\/2\/library\/logging.html\">https:\/\/docs.python.org\/2\/library\/logging.html<\/a><br \/>\n<a href=\"http:\/\/www.blog.pythonlibrary.org\/2012\/08\/02\/python-101-an-intro-to-logging\">http:\/\/www.blog.pythonlibrary.org\/2012\/08\/02\/python-101-an-intro-to-logging<\/a><\/p>\n<p>Complete Python code for this tutorial can be found on my github here:<br \/>\n<a href=\"https:\/\/github.com\/chris-relaxing\/python-how-to-use-logging\">https:\/\/github.com\/chris-relaxing\/python-how-to-use-logging<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sending print statements to the console is very common in Python coding. It is simply a matter of using the key word print, followed by what you want printed to the screen. For example: # variables year = &#8216;2015&#8217; xldate = 41000 pvid_list = [&#8220;19615056&#8221;, &#8220;15612770&#8221;, &#8220;15612771&#8221;] # print a raw string print &#8220;Print this &hellip; <a href=\"https:\/\/bluegalaxy.info\/codewalk\/2018\/06\/04\/python-use-logging-module\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Python: How to use the logging module<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[4],"class_list":["post-2092","post","type-post","status-publish","format-standard","hentry","category-python-language","tag-python"],"_links":{"self":[{"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/posts\/2092","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/comments?post=2092"}],"version-history":[{"count":9,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/posts\/2092\/revisions"}],"predecessor-version":[{"id":2880,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/posts\/2092\/revisions\/2880"}],"wp:attachment":[{"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/media?parent=2092"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/categories?post=2092"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/tags?post=2092"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}