/usr/share/doc/python-structlog-doc/html/configuration.html is in python-structlog-doc 17.2.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | <!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>Configuration — structlog documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</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="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Thread Local Context" href="thread-local.html" />
<link rel="prev" title="Loggers" href="loggers.html" />
</head>
<body>
<div class="related" role="navigation" aria-label="related navigation">
<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="thread-local.html" title="Thread Local Context"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="loggers.html" title="Loggers"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">structlog documentation</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="configuration">
<span id="id1"></span><h1>Configuration<a class="headerlink" href="#configuration" title="Permalink to this headline">¶</a></h1>
<div class="section" id="global-defaults">
<h2>Global Defaults<a class="headerlink" href="#global-defaults" title="Permalink to this headline">¶</a></h2>
<p>To make logging as unintrusive and straight-forward to use as possible, <code class="docutils literal"><span class="pre">structlog</span></code> comes with a plethora of configuration options and convenience functions.
Let me start at the end and introduce you to the ultimate convenience function that relies purely on configuration: <code class="xref py py-func docutils literal"><span class="pre">structlog.get_logger()</span></code> (and its Twisted-friendly alias <code class="xref py py-func docutils literal"><span class="pre">structlog.getLogger()</span></code>).</p>
<p>The goal is to reduce your per-file logging boilerplate to:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">structlog</span> <span class="k">import</span> <span class="n">get_logger</span>
<span class="n">logger</span> <span class="o">=</span> <span class="n">get_logger</span><span class="p">()</span>
</pre></div>
</div>
<p>while still giving you the full power via configuration.</p>
<p>To achieve that you’ll have to call <code class="xref py py-func docutils literal"><span class="pre">structlog.configure()</span></code> on app initialization (of course, only if you’re not content with the defaults).
The <a class="reference internal" href="loggers.html#proc"><span class="std std-ref">example</span></a> from the previous chapter could thus have been written as following:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">configure</span><span class="p">(</span><span class="n">processors</span><span class="o">=</span><span class="p">[</span><span class="n">proc</span><span class="p">],</span> <span class="n">context_class</span><span class="o">=</span><span class="nb">dict</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">log</span> <span class="o">=</span> <span class="n">wrap_logger</span><span class="p">(</span><span class="n">PrintLogger</span><span class="p">())</span>
<span class="gp">>>> </span><span class="n">log</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s1">'hello world'</span><span class="p">)</span>
<span class="go">I got called with {'event': 'hello world'}</span>
<span class="go">{'event': 'hello world'}</span>
</pre></div>
</div>
<p>In fact, it could even be written like</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">configure</span><span class="p">(</span><span class="n">processors</span><span class="o">=</span><span class="p">[</span><span class="n">proc</span><span class="p">],</span> <span class="n">context_class</span><span class="o">=</span><span class="nb">dict</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">log</span> <span class="o">=</span> <span class="n">get_logger</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">log</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s1">'hello world'</span><span class="p">)</span>
<span class="go">I got called with {'event': 'hello world'}</span>
<span class="go">{'event': 'hello world'}</span>
</pre></div>
</div>
<p>because <code class="xref py py-class docutils literal"><span class="pre">PrintLogger</span></code> is the default <code class="docutils literal"><span class="pre">LoggerFactory</span></code> used (see <a class="reference internal" href="#logger-factories"><span class="std std-ref">Logger Factories</span></a>).</p>
<p><code class="docutils literal"><span class="pre">structlog</span></code> tries to behave in the least surprising way when it comes to handling defaults and configuration:</p>
<ol class="arabic simple">
<li>Arguments passed to <code class="xref py py-func docutils literal"><span class="pre">structlog.wrap_logger()</span></code> <em>always</em> take the highest precedence over configuration.
That means that you can overwrite whatever you’ve configured for each logger respectively.</li>
<li>If you leave them on <cite>None</cite>, <code class="docutils literal"><span class="pre">structlog</span></code> will check whether you’ve configured default values using <code class="xref py py-func docutils literal"><span class="pre">structlog.configure()</span></code> and uses them if so.</li>
<li>If you haven’t configured or passed anything at all, the default fallback values are used which means <code class="xref py py-class docutils literal"><span class="pre">collections.OrderedDict</span></code> for context and <code class="docutils literal"><span class="pre">[</span></code><code class="xref py py-class docutils literal"><span class="pre">StackInfoRenderer</span></code>, <code class="xref py py-func docutils literal"><span class="pre">format_exc_info()</span></code>, <code class="xref py py-class docutils literal"><span class="pre">KeyValueRenderer</span></code><code class="docutils literal"><span class="pre">]</span></code> for the processor chain, and <cite>False</cite> for <cite>cache_logger_on_first_use</cite>.</li>
</ol>
<p>If necessary, you can always reset your global configuration back to default values using <code class="xref py py-func docutils literal"><span class="pre">structlog.reset_defaults()</span></code>.
That can be handy in tests.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>Since you will call <code class="xref py py-func docutils literal"><span class="pre">structlog.wrap_logger()</span></code> (or one of the <code class="docutils literal"><span class="pre">get_logger()</span></code> functions) most likely at import time and thus before you had a chance to configure <code class="docutils literal"><span class="pre">structlog</span></code>, they return a <strong>proxy</strong> that returns a correct wrapped logger on first <code class="docutils literal"><span class="pre">bind()</span></code>/<code class="docutils literal"><span class="pre">new()</span></code>.</p>
<p>Therefore, you must not call <code class="docutils literal"><span class="pre">new()</span></code> or <code class="docutils literal"><span class="pre">bind()</span></code> in module scope!
Use <code class="xref py py-func docutils literal"><span class="pre">get_logger()</span></code>’s <code class="docutils literal"><span class="pre">initial_values</span></code> to achieve pre-populated contexts.</p>
<p class="last">To enable you to log with the module-global logger, it will create a temporary BoundLogger and relay the log calls to it on <em>each call</em>.
Therefore if you have nothing to bind but intend to do lots of log calls in a function, it makes sense performance-wise to create a local logger by calling <code class="docutils literal"><span class="pre">bind()</span></code> or <code class="docutils literal"><span class="pre">new()</span></code> without any parameters.
See also <a class="reference internal" href="performance.html"><span class="doc">Performance</span></a>.</p>
</div>
</div>
<div class="section" id="logger-factories">
<span id="id2"></span><h2>Logger Factories<a class="headerlink" href="#logger-factories" title="Permalink to this headline">¶</a></h2>
<p>To make <code class="xref py py-func docutils literal"><span class="pre">structlog.get_logger()</span></code> work, one needs one more option that hasn’t been discussed yet: <code class="docutils literal"><span class="pre">logger_factory</span></code>.</p>
<p>It is a callable that returns the logger that gets wrapped and returned.
In the simplest case, it’s a function that returns a logger – or just a class.
But you can also pass in an instance of a class with a <code class="docutils literal"><span class="pre">__call__</span></code> method for more complicated setups.</p>
<div class="versionadded">
<p><span class="versionmodified">New in version 0.4.0: </span><code class="xref py py-func docutils literal"><span class="pre">structlog.get_logger()</span></code> can optionally take positional parameters.</p>
</div>
<p>These will be passed to the logger factories.
For example, if you use run <code class="docutils literal"><span class="pre">structlog.get_logger('a</span> <span class="pre">name')</span></code> and configure <code class="docutils literal"><span class="pre">structlog</span></code> to use the standard library <code class="xref py py-class docutils literal"><span class="pre">LoggerFactory</span></code> which has support for positional parameters, the returned logger will have the name <code class="docutils literal"><span class="pre">'a</span> <span class="pre">name'</span></code>.</p>
<p>When writing custom logger factories, they should always accept positional parameters even if they don’t use them.
That makes sure that loggers are interchangeable.</p>
<p>For the common cases of standard library logging and Twisted logging, <code class="docutils literal"><span class="pre">structlog</span></code> comes with two factories built right in:</p>
<ul class="simple">
<li><code class="xref py py-class docutils literal"><span class="pre">structlog.stdlib.LoggerFactory</span></code></li>
<li><code class="xref py py-class docutils literal"><span class="pre">structlog.twisted.LoggerFactory</span></code></li>
</ul>
<p>So all it takes to use <code class="docutils literal"><span class="pre">structlog</span></code> with standard library logging is this:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">structlog</span> <span class="k">import</span> <span class="n">get_logger</span><span class="p">,</span> <span class="n">configure</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">structlog.stdlib</span> <span class="k">import</span> <span class="n">LoggerFactory</span>
<span class="gp">>>> </span><span class="n">configure</span><span class="p">(</span><span class="n">logger_factory</span><span class="o">=</span><span class="n">LoggerFactory</span><span class="p">())</span>
<span class="gp">>>> </span><span class="n">log</span> <span class="o">=</span> <span class="n">get_logger</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">log</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s1">'this is too easy!'</span><span class="p">)</span>
<span class="go">event='this is too easy!'</span>
</pre></div>
</div>
<p>By using <code class="docutils literal"><span class="pre">structlog</span></code>’s <code class="xref py py-class docutils literal"><span class="pre">structlog.stdlib.LoggerFactory</span></code>, it is also ensured that variables like function names and line numbers are expanded correctly in your log format.</p>
<p>The <a class="reference internal" href="examples.html#twisted-example"><span class="std std-ref">Twisted example</span></a> shows how easy it is for Twisted.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last"><cite>LoggerFactory()</cite>-style factories always need to get passed as <em>instances</em> like in the examples above.
While neither allows for customization using parameters yet, they may do so in the future.</p>
</div>
<p>Calling <code class="xref py py-func docutils literal"><span class="pre">structlog.get_logger()</span></code> without configuration gives you a perfectly useful <code class="xref py py-class docutils literal"><span class="pre">structlog.PrintLogger</span></code> with the default values explained above.
I don’t believe silent loggers are a sensible default.</p>
</div>
<div class="section" id="where-to-configure">
<h2>Where to Configure<a class="headerlink" href="#where-to-configure" title="Permalink to this headline">¶</a></h2>
<p>The best place to perform your configuration varies with applications and frameworks.
Ideally as late as possible but <em>before</em> non-framework (i.e. your) code is executed.
If you use standard library’s logging, it makes sense to configure them next to each other.</p>
<dl class="docutils">
<dt><strong>Django</strong></dt>
<dd>Django has to date unfortunately no concept of an application assembler or “app is done” hooks.
Therefore the bottom of your <code class="docutils literal"><span class="pre">settings.py</span></code> will have to do.</dd>
<dt><strong>Flask</strong></dt>
<dd>See <a class="reference external" href="http://flask.pocoo.org/docs/errorhandling/">Logging Application Errors</a>.</dd>
<dt><strong>Pyramid</strong></dt>
<dd><a class="reference external" href="http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/startup.html#the-startup-process">Application constructor</a>.</dd>
<dt><strong>Twisted</strong></dt>
<dd>The <a class="reference external" href="https://twistedmatrix.com/documents/current/core/howto/plugin.html">plugin definition</a> is the best place.
If your app is not a plugin, put it into your <a class="reference external" href="https://twistedmatrix.com/documents/current/core/howto/application.html">tac file</a> (and then <a class="reference external" href="https://bitbucket.org/jerub/twisted-plugin-example">learn</a> about plugins).</dd>
</dl>
<p>If you have no choice but <em>have</em> to configure on import time in module-global scope, or can’t rule out for other reasons that that your <code class="xref py py-func docutils literal"><span class="pre">structlog.configure()</span></code> gets called more than once, <code class="docutils literal"><span class="pre">structlog</span></code> offers <code class="xref py py-func docutils literal"><span class="pre">structlog.configure_once()</span></code> that raises a warning if <code class="docutils literal"><span class="pre">structlog</span></code> has been configured before (no matter whether using <code class="xref py py-func docutils literal"><span class="pre">structlog.configure()</span></code> or <code class="xref py py-func docutils literal"><span class="pre">configure_once()</span></code>) but doesn’t change anything.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Configuration</a><ul>
<li><a class="reference internal" href="#global-defaults">Global Defaults</a></li>
<li><a class="reference internal" href="#logger-factories">Logger Factories</a></li>
<li><a class="reference internal" href="#where-to-configure">Where to Configure</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="loggers.html"
title="previous chapter">Loggers</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="thread-local.html"
title="next chapter">Thread Local Context</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/configuration.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<div><input type="text" name="q" /></div>
<div><input type="submit" value="Go" /></div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<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="thread-local.html" title="Thread Local Context"
>next</a> |</li>
<li class="right" >
<a href="loggers.html" title="Loggers"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">structlog documentation</a> »</li>
</ul>
</div>
<div class="footer" role="contentinfo">
© Copyright 2017, Hynek Schlawack.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.6.5.
</div>
</body>
</html>
|