<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Logging on Han's XYZ</title><link>https://han8931.github.io/tags/logging/</link><description>Recent content in Logging on Han's XYZ</description><generator>Hugo</generator><language>en</language><managingEditor>tabularasa8931@gmail.com (Han)</managingEditor><webMaster>tabularasa8931@gmail.com (Han)</webMaster><copyright>This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.</copyright><lastBuildDate>Mon, 15 Sep 2025 19:39:28 +0900</lastBuildDate><atom:link href="https://han8931.github.io/tags/logging/index.xml" rel="self" type="application/rss+xml"/><item><title>Introduction to logging in Python</title><link>https://han8931.github.io/python-logging/</link><pubDate>Sat, 17 May 2025 00:00:00 +0000</pubDate><author>tabularasa8931@gmail.com (Han)</author><guid>https://han8931.github.io/python-logging/</guid><description>&lt;h2 id="a-gentle-practical-introduction-to-logging-in-python"&gt;A gentle, practical introduction to &lt;code&gt;logging&lt;/code&gt; in Python&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id="why-bother-with-a-dedicated-logging-library"&gt;Why bother with a dedicated logging library?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prints don’t scale.&lt;/strong&gt; &lt;code&gt;print()&lt;/code&gt; is fine during quick experiments, but real programs need a record that can be filtered, rotated, or shipped elsewhere.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Separation of concerns.&lt;/strong&gt; You decide &lt;em&gt;what&lt;/em&gt; to log in your code; &lt;code&gt;logging&lt;/code&gt; decides &lt;em&gt;where&lt;/em&gt; and &lt;em&gt;how&lt;/em&gt; to write it (console, file, etc.).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Built-in, no extra dependency.&lt;/strong&gt; The standard library’s &lt;code&gt;logging&lt;/code&gt; module is powerful enough for most applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="core-concepts"&gt;Core concepts&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Concept&lt;/th&gt;
 &lt;th&gt;Role in the ecosystem&lt;/th&gt;
 &lt;th&gt;Typical examples&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Logger&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;The entry point your code calls (&lt;code&gt;logger.info(...)&lt;/code&gt;). You can have many, one per module.&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;&amp;quot;__main__&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;my_package.worker&amp;quot;&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Handler&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Decides &lt;em&gt;where&lt;/em&gt; the record goes.&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;StreamHandler&lt;/code&gt; (stdout), &lt;code&gt;FileHandler&lt;/code&gt;, &lt;code&gt;TimedRotatingFileHandler&lt;/code&gt;, &lt;code&gt;SMTPHandler&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Formatter&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Decides &lt;em&gt;how&lt;/em&gt; the record looks.&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;'%(asctime)s - %(levelname)s - %(name)s - %(message)s'&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="a-minimal-logger"&gt;A minimal logger&lt;/h3&gt;
&lt;div class="code-block code-line-numbers open" style="counter-reset: code-block 0"&gt;
 &lt;div class="code-header language-python"&gt;
 &lt;span class="code-title"&gt;&lt;i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"&gt;&lt;/i&gt;&lt;/span&gt;
 &lt;span class="ellipses"&gt;&lt;i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"&gt;&lt;/i&gt;&lt;/span&gt;
 &lt;span class="copy" title="Copy to clipboard"&gt;&lt;i class="far fa-copy fa-fw" aria-hidden="true"&gt;&lt;/i&gt;&lt;/span&gt;
 &lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s2"&gt; | &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Hello, world!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;basicConfig&lt;/code&gt; is a one-liner good for small scripts.&lt;/li&gt;
&lt;li&gt;In bigger projects, mixing multiple modules / log files, you&amp;rsquo;ll want finer control.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="rotating-files-at-midnight"&gt;Rotating files at midnight&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Rotating a log file means creating a new log file after a certain time or size limit is reached&lt;/strong&gt;. In this case, a new file is created every night at midnight. Only the most recent two log files are kept—yesterday&amp;rsquo;s and today’s—while older ones are deleted automatically.&lt;/p&gt;</description></item></channel></rss>