[code.view]

[top] / python / PyMOTW / docs / logging / index.html


<!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. &mdash; 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> &raquo;</li>
          <li><a href="../generic_os.html" accesskey="U">Generic Operating System Services</a> &raquo;</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 &#8211; 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 &#8211; Command line option and argument parsing.</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="../getpass/index.html"
                        title="next chapter">getpass &#8211; 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 &#8211; 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&#8217;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">&#39;logging_example.out&#39;</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">&#39;This message should go to the log file&#39;</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">&#39;rt&#39;</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">&#39;FILE:&#39;</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">&#39;logging_rotatingfile_example.out&#39;</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">&#39;MyLogger&#39;</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">&#39;i = </span><span class="si">%d</span><span class="s">&#39;</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">&#39;</span><span class="si">%s</span><span class="s">*&#39;</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 &gt; 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 &lt; 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">&#39;debug&#39;</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">&#39;info&#39;</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">&#39;warning&#39;</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">&#39;error&#39;</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">&#39;critical&#39;</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">&gt;</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">&#39;This is a debug message&#39;</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">&#39;This is an info message&#39;</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">&#39;This is a warning message&#39;</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">&#39;This is an error message&#39;</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">&#39;This is a critical error message&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Run the script with an argument like &#8216;debug&#8217; or &#8216;warning&#8217; 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 &#8216;root&#8217; 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">&#39;package1.module1&#39;</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">&#39;package2.module2&#39;</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">&#39;This message comes from one module&#39;</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">&#39;And this message comes from another module&#39;</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> &raquo;</li>
          <li><a href="../generic_os.html" >Generic Operating System Services</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; 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>

[top] / python / PyMOTW / docs / logging / index.html

contact | logmethods.com