{"id":21454,"date":"2022-11-29T16:03:26","date_gmt":"2022-11-29T10:33:26","guid":{"rendered":"https:\/\/java2blog.com\/?p=21454"},"modified":"2022-11-30T11:40:24","modified_gmt":"2022-11-30T06:10:24","slug":"log-to-stdout-python","status":"publish","type":"post","link":"https:\/\/java2blog.com\/log-to-stdout-python\/","title":{"rendered":"How to Log to Stdout in Python"},"content":{"rendered":"<div id=\"toc_container\" class=\"toc_light_blue no_bullets\"><p class=\"toc_title\">Table of Contents<\/p><ul class=\"toc_list\"><li><a href=\"#Use_loggingbasicConfig_to_log_to_stdout\">Use logging.basicConfig() to log to stdout<\/a><\/li><li><a href=\"#Use_loggingStreamHandler_to_log_to_stdout\">Use logging.StreamHandler() to log to stdout<\/a><\/li><\/ul><\/div>\n<h2><span id=\"Use_loggingbasicConfig_to_log_to_stdout\">Use <code>logging.basicConfig()<\/code> to log to <code>stdout<\/code><\/span><\/h2>\n<p>To log to <code>stdout<\/code> in Python:<\/p>\n<ul>\n<li>Specify the format in which we want to have all logs.<\/li>\n<li>Use the helper function <code>.basicConfig()<\/code> to perform basic logging for the logging system.<\/li>\n<li>Use <code>.getLogger()<\/code> to create a logger with the specified name (if it is); otherwise, it will create a <code>root<\/code> logger.<\/li>\n<li>Use <code>.error()<\/code> to log the <code>ERROR<\/code> level message on the console.<\/li>\n<\/ul>\n<pre code=\"python\" title=\"Use logging.basicConfig() Method\">\nimport logging\nlog_format = \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\" \nlogging.basicConfig(format = log_format, level = logging.ERROR)\n\nlogger = logging.getLogger()\nlogger.error(\"Logging First Error\")\n<\/pre>\n<p>The above code block will display the following output on the console.<\/p>\n<pre title=\"OUTPUT\">\n2022-11-28 17:00:46,865 - root - ERROR - Logging First Error\n<\/pre>\n<p>We used a helper function known as <code>.basicConfig()<\/code> to perform basic logging by creating the <code>StreamHandler<\/code> with the specified <code>Formatter<\/code> and adding it to a <code>root<\/code> logger.<\/p>\n<p>You might have a few questions by reading the above sentence, for instance, what is <code>StreamHandler<\/code>, how they are created, what is <code>root<\/code>, and how it is being added to the <code>root<\/code> logger. Let&#8217;s address these questions before diving into more details of the <code>.basicConfig()<\/code> function.<\/p>\n<p>The <code>StreamHandler<\/code> is a handler used for logging to the console. We created a <code>root<\/code> logger in our application by calling <code>logging.getLogger()<\/code>, which creates a <code>root<\/code> logger by default.<\/p>\n<p>We can also name the logger of our choice by passing a custom name to this function, for example, <code>logging.getLogger(&quot;MyLogger&quot;)<\/code>. The <code>logger.error()<\/code> invokes the <code>.basicConfig()<\/code>; this is how it is added to the <code>root<\/code> logger.<\/p>\n<p>Now, the point is how we are creating <code>StreamHandler<\/code>. The <code>handlers<\/code> is one of the parameters that we can set while using the <code>.basicConfig()<\/code> method. The <code>handler<\/code> parameter is iterable and used to have the handlers, for instance, <code>logging.FilHandler()<\/code> and <code>logging.StreamHandler()<\/code>.<\/p>\n<p>If we don&#8217;t set the <code>handler<\/code> parameter, it acts as <code>StreamHandler<\/code> by default. This is how <code>StreamHandler<\/code> is created. You can learn more about it <a href=\"https:\/\/docs.python.org\/3\/howto\/logging.html#what-happens-if-no-configuration-is-provided\" target=\"_blank\" rel=\"noopener\">here<\/a>. Now, let&#8217;s return to the <code>.basicConfig()<\/code> method and explore more about it below.<\/p>\n<p>The <code>.basicConfig()<\/code> does nothing if the <code>root<\/code> logger has configured handlers already unless <code>force<\/code> is set to <code>True<\/code>. Here, configured handlers mean that the <code>.basicConfig()<\/code> method has a <code>handlers<\/code> parameter set something as follows:<\/p>\n<pre code=\"python\" title=\"Passing StreamHandler to basicConfig() method\">\nstream_handler = logging.StreamHandler(sys.stdout)\nstream_handler.setFormatter(logging.Formatter(\"%(message)s\"))\n\nlogging.basicConfig(level=logging.ERROR,\n                    handlers=[ logging.FileHandler(\"file.log\"),\n                    stream_handler\n])\n<\/pre>\n<p>In our code example, we passed two parameters to <code>.basicConfig()<\/code> function that are briefly explained below:<\/p>\n<ol>\n<li>\n<p><code>format<\/code> &#8211; It is used to specify a particular format to display logs. If it is not given, the <code>.basicConfig()<\/code> will log in default format as <code>logger level: logger name: log message<\/code>. For instance, <code>ERROR: root: Logging First Error<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>level<\/code> &#8211; It denotes the logger&#8217;s level. We have six levels in the <code>logging<\/code> module: <code>CRITICAL<\/code>, <code>ERROR<\/code>, <code>WARNING<\/code>, <code>INFO<\/code>, <code>DEBUG<\/code>, and <code>NOTSET<\/code>. If no <code>level<\/code> parameter is given, it will set the logging level to <code>NOTSET<\/code> in the <code>logging<\/code> module.<\/p>\n<\/li>\n<\/ol>\n<p>Remember that the <code>info()<\/code>, <code>debug()<\/code>, <code>error()<\/code>, <code>warning()<\/code>, and <code>critical()<\/code> functions will automatically invoke <code>.basicConfig()<\/code> if any handler is not defined for a <code>root<\/code> logger.<\/p>\n<p>Make sure to distinguish these logging functions from logging levels. The logging levels are not the same as logging functions but are the constants with some associated integer number.<\/p>\n<p>For instance, <code>logging.ERROR = 10<\/code>. Similarly, <code>CRITICAL<\/code>, <code>WARNING<\/code>, <code>INFO<\/code>, <code>DEBUG<\/code>, and <code>NOTSET<\/code> also have some associated integers.<\/p>\n<p>Next, we called the <code>logging.getLogger()<\/code> method to create a <code>root<\/code> logger. Finally, we used the <code>logging.error()<\/code> method with a logging level <code>ERROR<\/code> to log messages on a <code>root<\/code> logger.<\/p>\n<h2><span id=\"Use_loggingStreamHandler_to_log_to_stdout\">Use <code>logging.StreamHandler()<\/code> to log to <code>stdout<\/code><\/span><\/h2>\n<p>To log to <code>stdout<\/code>:<\/p>\n<ul>\n<li>Use <code>.getLogger()<\/code> to create a logger named <code>MyFirstLogger<\/code>. Note that the <code>name<\/code> parameter is optional.<\/li>\n<li>Use <code>.StreamHandler()<\/code> to log to the console.<\/li>\n<li>Use <code>.Formatter()<\/code> to get a <code>Formatter<\/code> class&#8217; instance initialized with the format string; this format string will be used while displaying log messages on the console or file. <\/li>\n<li>Next, use <code>.setFormatter()<\/code> to set the formatter (created in the previous step) on <code>StreamHandler<\/code>.<\/li>\n<li>Use <code>.addHandler()<\/code> to add the <code>stream_handler<\/code> to our logger.<\/li>\n<li>Use <code>.error()<\/code> to log the <code>ERROR<\/code> level message on the console.<\/li>\n<\/ul>\n<pre code=\"python\" title=\"Use logging.StreamHandler() Method\">\nimport logging\nimport sys\nlog_format = \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\nlogger = logging.getLogger(\"MyFirstLogger\")\n\nstream_handler = logging.StreamHandler(stream = sys.stdout)\nformatter = logging.Formatter(log_format)\n\nstream_handler.setFormatter(formatter)\nlogger.addHandler(stream_handler)\n\nlogger.error(\"Logging First Error\")\n<\/pre>\n<p>This code will print the log on the console as follows.<\/p>\n<pre title=\"OUTPUT\">\n2022-11-29 04:30:10,959 - MyFirstLogger - ERROR - Logging First Error\n<\/pre>\n<p>We used <code>.getLogger()<\/code> to create a logger with a name of our choice. We can also call this method without passing the <code>name<\/code> parameter. In that case, this function would create a <code>root<\/code> logger.<\/p>\n<p>Next, we used a <code>.StreamHandler()<\/code> handler by setting a <code>stream<\/code> parameter to <code>sys.stdout<\/code> to log to the console. Here, we can change the value of the <code>stream<\/code> parameter based on where to send logging output, for instance, <code>sys.stdout<\/code>, <code>sys.stderr<\/code>, file-like object or any object supporting <code>flush()<\/code> and <code>write()<\/code>.<\/p>\n<p>Note that we have different handlers in the <code>logging<\/code> module that we can choose from based on project requirements, such as <code>SocketHandler<\/code>, <code>RotatingFileHandle<\/code>, <code>DatagramHandler<\/code>, <code>NullHandler<\/code>, and <code>FileHandler<\/code>.<\/p>\n<p>We used <code>StreamHandler()<\/code> to log to the console, but you can also use <code>FileHandler()<\/code> to log to the file. Check the <a href=\"https:\/\/docs.python.org\/3\/library\/logging.handlers.html#module-logging.handlers\" target=\"_blank\" rel=\"noopener\">Python documentation<\/a> for more details for each of the logging handlers.<\/p>\n<p>Then, we used the <code>.Formatter()<\/code> function by specifying a <code>log_format<\/code>, which contained a string format to format logs. The <code>.Formatters()<\/code> are accountable for transforming internal log records into human-readable string formats.<\/p>\n<p>Following the previous step, we used <code>.setFormatter()<\/code> to set the formatter on the <code>SteamHandler<\/code>, which means the <code>logging<\/code> module will use this <code>formatter<\/code> to format all the messages before displaying them on the console.<\/p>\n<p>Next, we used <code>.addHandler()<\/code> to add a stream handler to the logger and finally used <code>.error()<\/code> to log the <code>ERROR<\/code> level message on the console.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Table of ContentsUse logging.basicConfig() to log to stdoutUse logging.StreamHandler() to log to stdout Use logging.basicConfig() to log to stdout To log to stdout in Python: Specify the format in which we want to have all logs. Use the helper function .basicConfig() to perform basic logging for the logging system. Use .getLogger() to create a logger [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_mi_skip_tracking":false},"categories":[145],"tags":[],"_links":{"self":[{"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/posts\/21454"}],"collection":[{"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/comments?post=21454"}],"version-history":[{"count":8,"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/posts\/21454\/revisions"}],"predecessor-version":[{"id":21500,"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/posts\/21454\/revisions\/21500"}],"wp:attachment":[{"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/media?parent=21454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/categories?post=21454"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/java2blog.com\/wp-json\/wp\/v2\/tags?post=21454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}