<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>logging – Report status, error, and informational messages. — Python Module of the Week</title> <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '1.132', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="author" title="About these documents" href="../about.html" /> <link rel="top" title="Python Module of the Week" href="../index.html" /> <link rel="up" title="Generic Operating System Services" href="../generic_os.html" /> <link rel="next" title="getpass – Prompt the user for a password without echoing." href="../getpass/index.html" /> <link rel="prev" title="argparse – Command line option and argument parsing." href="../argparse/index.html" /> </head> <body> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li class="right" > <a href="../getpass/index.html" title="getpass – Prompt the user for a password without echoing." accesskey="N">next</a> |</li> <li class="right" > <a href="../argparse/index.html" title="argparse – Command line option and argument parsing." accesskey="P">previous</a> |</li> <li><a href="../contents.html">PyMOTW</a> »</li> <li><a href="../generic_os.html" accesskey="U">Generic Operating System Services</a> »</li> </ul> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../contents.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">logging – Report status, error, and informational messages.</a><ul> <li><a class="reference internal" href="#logging-in-applications">Logging in Applications</a><ul> <li><a class="reference internal" href="#logging-to-a-file">Logging to a File</a></li> <li><a class="reference internal" href="#rotating-log-files">Rotating Log Files</a></li> <li><a class="reference internal" href="#verbosity-levels">Verbosity Levels</a></li> </ul> </li> <li><a class="reference internal" href="#logging-in-libraries">Logging in Libraries</a><ul> <li><a class="reference internal" href="#naming-logger-instances">Naming Logger Instances</a></li> </ul> </li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="../argparse/index.html" title="previous chapter">argparse – Command line option and argument parsing.</a></p> <h4>Next topic</h4> <p class="topless"><a href="../getpass/index.html" title="next chapter">getpass – Prompt the user for a password without echoing.</a></p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../_sources/logging/index.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../search.html" method="get"> <input type="text" name="q" size="18" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="module-logging"> <span id="logging-report-status-error-and-informational-messages"></span><h1>logging – Report status, error, and informational messages.<a class="headerlink" href="#module-logging" title="Permalink to this headline">¶</a></h1> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Purpose:</th><td class="field-body">Report status, error, and informational messages.</td> </tr> <tr class="field"><th class="field-name">Python Version:</th><td class="field-body">2.3</td> </tr> </tbody> </table> <p>The <a class="reference internal" href="#module-logging" title="logging: Report status, error, and informational messages."><tt class="xref py py-mod docutils literal"><span class="pre">logging</span></tt></a> module defines a standard API for reporting errors and status information from applications and libraries. The key benefit of having the logging API provided by a standard library module is that all Python modules can participate in logging, so an application’s log can include messages from third-party modules.</p> <div class="section" id="logging-in-applications"> <h2>Logging in Applications<a class="headerlink" href="#logging-in-applications" title="Permalink to this headline">¶</a></h2> <p>There are two perspectives for examining logging. Application developers set up the <a class="reference internal" href="#module-logging" title="logging: Report status, error, and informational messages."><tt class="xref py py-mod docutils literal"><span class="pre">logging</span></tt></a> module, directing the messages to appropriate output channels. It is possible to log messages with different verbosity levels or to different destinations. Handlers for writing log messages to files, HTTP GET/POST locations, email via SMTP, generic sockets, or OS-specific logging mechanisms are all included, and it is possible to create custom log destination classes for special requirements not handled by any of the built-in classes.</p> <div class="section" id="logging-to-a-file"> <h3>Logging to a File<a class="headerlink" href="#logging-to-a-file" title="Permalink to this headline">¶</a></h3> <p>Most applications are probably going to want to log to a file. Use the <tt class="xref py py-func docutils literal"><span class="pre">basicConfig()</span></tt> function to set up the default handler so that debug messages are written to a file.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">logging</span> <span class="n">LOG_FILENAME</span> <span class="o">=</span> <span class="s">'logging_example.out'</span> <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="n">LOG_FILENAME</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">,</span> <span class="p">)</span> <span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'This message should go to the log file'</span><span class="p">)</span> <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">LOG_FILENAME</span><span class="p">,</span> <span class="s">'rt'</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">body</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="k">finally</span><span class="p">:</span> <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="k">print</span> <span class="s">'FILE:'</span> <span class="k">print</span> <span class="n">body</span> </pre></div> </div> <p>After running the script, the log message is written to <tt class="docutils literal"><span class="pre">logging_example.out</span></tt>:</p> <div class="highlight-python"><pre>$ python logging_file_example.py FILE: DEBUG:root:This message should go to the log file</pre> </div> </div> <div class="section" id="rotating-log-files"> <h3>Rotating Log Files<a class="headerlink" href="#rotating-log-files" title="Permalink to this headline">¶</a></h3> <p>Running the script repeatedly causes more messages to be appended to the file. To create a new file each time the program runs, pass a <tt class="docutils literal"><span class="pre">filemode</span></tt> argument to <tt class="xref py py-func docutils literal"><span class="pre">basicConfig()</span></tt> with a value of <tt class="docutils literal"><span class="pre">'w'</span></tt>. Rather than managing the creation of files this way, though, it is simpler to use a <tt class="xref py py-class docutils literal"><span class="pre">RotatingFileHandler</span></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="nn">logging</span> <span class="kn">import</span> <span class="nn">logging.handlers</span> <span class="n">LOG_FILENAME</span> <span class="o">=</span> <span class="s">'logging_rotatingfile_example.out'</span> <span class="c"># Set up a specific logger with our desired output level</span> <span class="n">my_logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'MyLogger'</span><span class="p">)</span> <span class="n">my_logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">)</span> <span class="c"># Add the log message handler to the logger</span> <span class="n">handler</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">RotatingFileHandler</span><span class="p">(</span><span class="n">LOG_FILENAME</span><span class="p">,</span> <span class="n">maxBytes</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">backupCount</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="p">)</span> <span class="n">my_logger</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span> <span class="c"># Log some messages</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span> <span class="n">my_logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'i = </span><span class="si">%d</span><span class="s">'</span> <span class="o">%</span> <span class="n">i</span><span class="p">)</span> <span class="c"># See what files are created</span> <span class="n">logfiles</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s">'</span><span class="si">%s</span><span class="s">*'</span> <span class="o">%</span> <span class="n">LOG_FILENAME</span><span class="p">)</span> <span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">logfiles</span><span class="p">:</span> <span class="k">print</span> <span class="n">filename</span> </pre></div> </div> <p>The result should be six separate files, each with part of the log history for the application:</p> <div class="highlight-python"><pre>$ python logging_rotatingfile_example.py logging_rotatingfile_example.out logging_rotatingfile_example.out.1 logging_rotatingfile_example.out.2 logging_rotatingfile_example.out.3 logging_rotatingfile_example.out.4 logging_rotatingfile_example.out.5</pre> </div> <p>The most current file is always <tt class="docutils literal"><span class="pre">logging_rotatingfile_example.out</span></tt>, and each time it reaches the size limit it is renamed with the suffix <tt class="docutils literal"><span class="pre">.1</span></tt>. Each of the existing backup files is renamed to increment the suffix (<tt class="docutils literal"><span class="pre">.1</span></tt> becomes <tt class="docutils literal"><span class="pre">.2</span></tt>, etc.) and the <tt class="docutils literal"><span class="pre">.5</span></tt> file is erased.</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">Obviously this example sets the log length much much too small as an extreme example. Set <em>maxBytes</em> to a more appropriate value in a real program.</p> </div> </div> <div class="section" id="verbosity-levels"> <h3>Verbosity Levels<a class="headerlink" href="#verbosity-levels" title="Permalink to this headline">¶</a></h3> <p>Another useful feature of the <a class="reference internal" href="#module-logging" title="logging: Report status, error, and informational messages."><tt class="xref py py-mod docutils literal"><span class="pre">logging</span></tt></a> API is the ability to produce different messages at different log levels. This code to be instrumented with debug messages, for example, while setting the log level down so that those debug messages are not written on a production system.</p> <table border="1" class="docutils"> <colgroup> <col width="62%" /> <col width="38%" /> </colgroup> <thead valign="bottom"> <tr><th class="head">Level</th> <th class="head">Value</th> </tr> </thead> <tbody valign="top"> <tr><td>CRITICAL</td> <td>50</td> </tr> <tr><td>ERROR</td> <td>40</td> </tr> <tr><td>WARNING</td> <td>30</td> </tr> <tr><td>INFO</td> <td>20</td> </tr> <tr><td>DEBUG</td> <td>10</td> </tr> <tr><td>UNSET</td> <td>0</td> </tr> </tbody> </table> <p>The logger, handler, and log message call each specify a level. The log message is only emitted if the handler and logger are configured to emit messages of that level or higher. For example, if a message is <tt class="xref py py-const docutils literal"><span class="pre">CRITICAL</span></tt>, and the logger is set to <tt class="xref py py-const docutils literal"><span class="pre">ERROR</span></tt>, the message is emitted (50 > 40). If a message is a <tt class="xref py py-const docutils literal"><span class="pre">WARNING</span></tt>, and the logger is set to produce only messages set to <tt class="xref py py-const docutils literal"><span class="pre">ERROR</span></tt>, the message is not emitted (30 < 40).</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">logging</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="n">LEVELS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">'debug'</span><span class="p">:</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">,</span> <span class="s">'info'</span><span class="p">:</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">,</span> <span class="s">'warning'</span><span class="p">:</span><span class="n">logging</span><span class="o">.</span><span class="n">WARNING</span><span class="p">,</span> <span class="s">'error'</span><span class="p">:</span><span class="n">logging</span><span class="o">.</span><span class="n">ERROR</span><span class="p">,</span> <span class="s">'critical'</span><span class="p">:</span><span class="n">logging</span><span class="o">.</span><span class="n">CRITICAL</span><span class="p">,</span> <span class="p">}</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> <span class="n">level_name</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="n">level</span> <span class="o">=</span> <span class="n">LEVELS</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">level_name</span><span class="p">,</span> <span class="n">logging</span><span class="o">.</span><span class="n">NOTSET</span><span class="p">)</span> <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="n">level</span><span class="p">)</span> <span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'This is a debug message'</span><span class="p">)</span> <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'This is an info message'</span><span class="p">)</span> <span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'This is a warning message'</span><span class="p">)</span> <span class="n">logging</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">'This is an error message'</span><span class="p">)</span> <span class="n">logging</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s">'This is a critical error message'</span><span class="p">)</span> </pre></div> </div> <p>Run the script with an argument like ‘debug’ or ‘warning’ to see which messages show up at different levels:</p> <div class="highlight-python"><pre>$ python logging_level_example.py debug DEBUG:root:This is a debug message INFO:root:This is an info message WARNING:root:This is a warning message ERROR:root:This is an error message CRITICAL:root:This is a critical error message $ python logging_level_example.py info INFO:root:This is an info message WARNING:root:This is a warning message ERROR:root:This is an error message CRITICAL:root:This is a critical error message</pre> </div> </div> </div> <div class="section" id="logging-in-libraries"> <h2>Logging in Libraries<a class="headerlink" href="#logging-in-libraries" title="Permalink to this headline">¶</a></h2> <p>Developers of libraries, rather than applications, should also use <a class="reference internal" href="#module-logging" title="logging: Report status, error, and informational messages."><tt class="xref py py-mod docutils literal"><span class="pre">logging</span></tt></a>. For them, there is even less work to do. Simply create a logger instance for each context, using an appropriate name, and then log messages using the stanard levels. As long as a library uses the logging API with consistent naming and level selections, the application can be configured to show or hide messages from the library, as desired.</p> <div class="section" id="naming-logger-instances"> <h3>Naming Logger Instances<a class="headerlink" href="#naming-logger-instances" title="Permalink to this headline">¶</a></h3> <p>All of the previous log messages all have ‘root’ embedded in them. The <a class="reference internal" href="#module-logging" title="logging: Report status, error, and informational messages."><tt class="xref py py-mod docutils literal"><span class="pre">logging</span></tt></a> module supports a hierarchy of loggers with different names. An easy way to tell where a specific log message comes from is to use a separate logger object for each module. Every new logger inherits the configuration of its parent, and log messages sent to a logger include the name of that logger. Optionally, each logger can be configured differently, so that messages from different modules are handled in different ways. Below is an example of how to log from different modules so it is easy to trace the source of the message:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">logging</span> <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">WARNING</span><span class="p">)</span> <span class="n">logger1</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'package1.module1'</span><span class="p">)</span> <span class="n">logger2</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'package2.module2'</span><span class="p">)</span> <span class="n">logger1</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'This message comes from one module'</span><span class="p">)</span> <span class="n">logger2</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'And this message comes from another module'</span><span class="p">)</span> </pre></div> </div> <p>And the output:</p> <div class="highlight-python"><pre>$ python logging_modules_example.py WARNING:package1.module1:This message comes from one module WARNING:package2.module2:And this message comes from another module</pre> </div> <p>There are many, many, more options for configuring logging, including different log message formatting options, having messages delivered to multiple destinations, and changing the configuration of a long-running application on the fly using a socket interface. All of these options are covered in depth in the library module documentation.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <dl class="last docutils"> <dt><a class="reference external" href="http://docs.python.org/library/logging.html">logging</a></dt> <dd>The standard library documentation for this module.</dd> </dl> </div> </div> </div> </div> </div> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li class="right" > <a href="../getpass/index.html" title="getpass – Prompt the user for a password without echoing." >next</a> |</li> <li class="right" > <a href="../argparse/index.html" title="argparse – Command line option and argument parsing." >previous</a> |</li> <li><a href="../contents.html">PyMOTW</a> »</li> <li><a href="../generic_os.html" >Generic Operating System Services</a> »</li> </ul> </div> <div class="footer"> © Copyright Doug Hellmann. Last updated on Oct 24, 2010. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>. <br/><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/" rel="license"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png"/></a> </div> </body> </html>