-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathLogging.html
More file actions
371 lines (356 loc) · 30.3 KB
/
Logging.html
File metadata and controls
371 lines (356 loc) · 30.3 KB
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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Logging and the logging module — Programming in Python 7.0 documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Debugging" href="Debugging.html" />
<link rel="prev" title="Mailroom – metaprogramming it!" href="../exercises/mailroom/mailroom-meta.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" style="background: #4b2e83" >
<a href="../index.html">
<img src="../_static/UWPCE_logo_full.png" class="logo" alt="Logo"/>
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Topics in the Program</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../topics/01-setting_up/index.html">1. Setting up your Environment</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/02-basic_python/index.html">2. Basic Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/03-recursion_booleans/index.html">3. Booleans and Recursion</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/04-sequences_iteration/index.html">4. Sequences and Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/05-text_handling/index.html">5. Basic Text Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/06-exceptions/index.html">6. Exception Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/07-unit_testing/index.html">7. Unit Testing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/08-dicts_sets/index.html">8. Dictionaries and Sets</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/09-files/index.html">9. File Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/10-modules_packages/index.html">10. Modules and Packages</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/11-argument_passing/index.html">11. Advanced Argument Passing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/12-comprehensions/index.html">12. Comprehensions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/13-intro_oo/index.html">13. Intro to Object Oriented Programing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/14-magic_methods/index.html">14. Properties and Magic Methods</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/15-subclassing/index.html">15. Subclassing and Inheritance</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/16-multiple_inheritance/index.html">16. Multiple Inheritance</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/17-functional_programming/index.html">17. Introduction to Functional Programming</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/18-advanced_testing/index.html">18. Advanced Testing</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../topics/99-extras/index.html">19. Extra Topics</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Pep8.html">Coding Style and Linting</a></li>
<li class="toctree-l2"><a class="reference internal" href="CodeReviews.html">Code Reviews</a></li>
<li class="toctree-l2"><a class="reference internal" href="PersistanceAndSerialization.html">Persistence and Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="Unicode.html">Unicode in Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="IteratorsAndGenerators.html">Iterators and Generators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Decorators.html">Decorators</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/mailroom/mailroom-decorator.html">Mailroom – Decoratoring it</a></li>
<li class="toctree-l2"><a class="reference internal" href="ContextManagers.html">Context Managers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/context-managers-exercise.html">A Couple Handy Context Managers</a></li>
<li class="toctree-l2"><a class="reference internal" href="MetaProgramming.html">Metaprogramming</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/mailroom/mailroom-meta.html">Mailroom – metaprogramming it!</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Logging and the logging module</a></li>
<li class="toctree-l2"><a class="reference internal" href="Debugging.html">Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoSQL.html">No SQL Databases</a></li>
<li class="toctree-l2"><a class="reference internal" href="GraphDatabases.html">Graph Databases</a></li>
<li class="toctree-l2"><a class="reference internal" href="Concurrency.html">Concurrent Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="Async.html">Asychronous Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="Coroutines.html">Notes on Coroutines</a></li>
<li class="toctree-l2"><a class="reference internal" href="ThreadingMultiprocessing.html">Threading and multiprocessing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/threaded_downloader.html">Threaded Web Scraper</a></li>
<li class="toctree-l2"><a class="reference internal" href="Profiling.html">Performance and Profiling</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" style="background: #4b2e83" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">Programming in Python</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content style-external-links">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home"></a> »</li>
<li><a href="../topics/99-extras/index.html"><span class="section-number">19. </span>Extra Topics</a> »</li>
<li>Logging and the logging module</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/modules/Logging.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul><div class="rst-breadcrumbs-buttons" role="navigation" aria-label="Sequential page navigation">
<a href="../exercises/mailroom/mailroom-meta.html" class="btn btn-neutral float-left" title="Mailroom – metaprogramming it!" accesskey="p"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="Debugging.html" class="btn btn-neutral float-right" title="Debugging" accesskey="n">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="logging-and-the-logging-module">
<span id="logging"></span><h1>Logging and the logging module<a class="headerlink" href="#logging-and-the-logging-module" title="Permalink to this headline"></a></h1>
<div class="section" id="what-is-logging">
<h2>What is Logging?<a class="headerlink" href="#what-is-logging" title="Permalink to this headline"></a></h2>
<p class="left small">What is logging?</p>
<blockquote class="left small">
<div><p>In computing, a logfile is a file that records either events that occur in an operating system or other software runs, or messages between different users of a communication software.</p>
<p>Logging is the act of keeping a log. In the simplest case, messages are written to a single logfile.</p>
</div></blockquote>
<p class="left small">(<a class="reference external" href="https://en.wikipedia.org/wiki/Logfile">https://en.wikipedia.org/wiki/Logfile</a>)</p>
<p class="left small">But in fact, a file is only <em>one</em> place to keep a log. You may want to send a log of what your program is doing to another system, to the console, or????</p>
<div class="section" id="what-to-log">
<h3>what to log?<a class="headerlink" href="#what-to-log" title="Permalink to this headline"></a></h3>
<p class="medium">What might you want to log?</p>
<p>System information</p>
<p>Error messages</p>
<p>Fine-grain tracing output</p>
</div>
<div class="section" id="the-logging-module">
<h3>The logging module<a class="headerlink" href="#the-logging-module" title="Permalink to this headline"></a></h3>
<p>A flexible logging system that comes with the standard library</p>
<p>Any module using the logging api can have logging output routed the same
as your code.</p>
<p>Resources for learning more:</p>
<p><a class="reference external" href="https://docs.python.org/3.5/howto/logging.html">https://docs.python.org/3.5/howto/logging.html</a></p>
<p><a class="reference external" href="http://docs.python-guide.org/en/latest/writing/logging/">http://docs.python-guide.org/en/latest/writing/logging/</a></p>
<p><a class="reference external" href="https://pymotw.com/3/logging/">https://pymotw.com/3/logging/</a></p>
</div>
<div class="section" id="why-not-print">
<h3>Why not <code class="docutils literal notranslate"><span class="pre">print()</span></code>?<a class="headerlink" href="#why-not-print" title="Permalink to this headline"></a></h3>
<p>We’ve all been using <code class="docutils literal notranslate"><span class="pre">print()</span></code> all over the place to track what’s going on in a program.</p>
<p>And I still use it – a lot.</p>
<p>But we (usually) don’t want all sorts of crap sent to stdout when the program is running in production.</p>
<p>So we comment out or delete those <code class="docutils literal notranslate"><span class="pre">print()</span></code> s – but if we wanted to know what the program was doing when developing – maybe we want to know when something unanticipated goes wrong, too?</p>
<p>The <code class="docutils literal notranslate"><span class="pre">logging</span></code> module give you a flexible system that allows you to monitor what’s going on in your system, when you need to, without cluttering things up when you don’t need it.</p>
</div>
</div>
<div class="section" id="background">
<h2>Background<a class="headerlink" href="#background" title="Permalink to this headline"></a></h2>
<p class="left">There are lots of good tutorials, etc, on the web for getting you started with <em>using</em> the logging module.</p>
<p class="left">But not much about how it works – how it is structured.</p>
<p class="left">I found it hard to get beyond the basics without that knowledge, so the following should help.</p>
<p class="left">The logging module provides a very flexible framework for customizing the logging in a simple or complex application.</p>
<div class="section" id="id1">
<h3>The <code class="docutils literal notranslate"><span class="pre">logging</span></code> module<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h3>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">logging</span>
</pre></div>
</div>
<p>The logging module not only provides the classes and functions required to build a logging system, but also a place to centrally manage the logging for an entire application.</p>
<p>This allows you to set up logging in one place, and everywhere in the app, the system can be used.</p>
<p>So, for instance, when developing and debugging, you may want logging messages to go to the console, but for deployment, to log files.</p>
<p>That configuration can be changed in one place.</p>
<p>(NOTE: this is one good reason to prefer logging over <code class="docutils literal notranslate"><span class="pre">print()</span></code>)</p>
</div>
<div class="section" id="logging-levels">
<h3>Logging “levels”<a class="headerlink" href="#logging-levels" title="Permalink to this headline"></a></h3>
<p>The built in way to catagorize logging messages is by level.</p>
<p>Levels are ordered numerically, so you can think of them as in order of importance, and it’s easy to choose how much detail you want.</p>
<p>The built-in set is:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">CRITICAL</span> <span class="mi">50</span>
<span class="n">ERROR</span> <span class="mi">40</span>
<span class="n">WARNING</span> <span class="mi">30</span>
<span class="n">INFO</span> <span class="mi">20</span>
<span class="n">DEBUG</span> <span class="mi">10</span>
</pre></div>
</div>
<p>so DEBUG provides the most detail, and CRITICAL you’d pretty much always want to see.</p>
<p>The logging API provides easy ways to send messages with these levels:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s1">'this is a debugging message'</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://docs.python.org/3/library/logging.html#levels">https://docs.python.org/3/library/logging.html#levels</a></p>
<p>similarly:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">logging</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s1">'this is a critical 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="s1">'this is a error 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="s1">'this is a warning 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="s1">'this is a information message'</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="s1">'this is a debug message'</span><span class="p">)</span>
</pre></div>
</div>
<p>Note that if you have not configured the logger, a default configuration will automatically be set up – so you can alwlays call these in yoru code, and it won’t fail.</p>
<p>This is actually particularly nice – you can add logging messages to your code, and they will “do the right thing” when run inside any application, whether it’s been spcifically configured or not.</p>
</div>
<div class="section" id="the-logging-classes">
<h3>The logging classes<a class="headerlink" href="#the-logging-classes" title="Permalink to this headline"></a></h3>
<p>The four main classes (you need to deal with) for logging</p>
<ul class="simple">
<li><p>Loggers - the interface for your code</p></li>
<li><p>Handlers - handle log routing</p></li>
<li><p>Filters - define which log messages to let through</p></li>
<li><p>Formatters - how the log messages get rendered</p></li>
</ul>
</div>
<div class="section" id="the-logger-class">
<h3>The <code class="docutils literal notranslate"><span class="pre">Logger</span></code> class<a class="headerlink" href="#the-logger-class" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">Logger</span></code> class is the core class that handles logging.</p>
<p>Messages get sent to a <code class="docutils literal notranslate"><span class="pre">Logger</span></code> instance, and it is responsibile for routing them appropriately.</p>
<p><code class="docutils literal notranslate"><span class="pre">Logger</span></code> s can be nested in a hierarchical fashion, so that a message can be sent to sub-loggers, and any messages not handled will be passed the chain to eventually be handled by the “root” logger.</p>
<p>There is always a root logger, and often the only one you need.</p>
<p>Each <code class="docutils literal notranslate"><span class="pre">Logger</span></code> represents a single logging channel.</p>
<p><code class="docutils literal notranslate"><span class="pre">Logger</span></code> instances are given text names, with module-style “dots” representing the hierarchy:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="s2">"main"</span>
<span class="s2">"main.sub_logger1"</span>
<span class="s2">"main.sub_logger2"</span>
<span class="o">...</span>
</pre></div>
</div>
<p>The “root” logger has no name, but is the root of all created loggers</p>
<p>The logging module keeps track of all the loggers you create, so you can reference them by name.</p>
</div>
<div class="section" id="logging-getlogger">
<h3><code class="docutils literal notranslate"><span class="pre">logging.getLogger()</span></code><a class="headerlink" href="#logging-getlogger" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">logging.getLogger()</span></code> function returns the logger you ask for:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">the_root_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="n">another_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="s2">"name"</span><span class="p">)</span>
</pre></div>
</div>
<p>If the logger you ask for doesn’t exist, <code class="docutils literal notranslate"><span class="pre">getLogger()</span></code> will create a new one for you by that name. (It won’t be configured, though…)</p>
<p>This whole system allows you to have multiple loggers without having to pass logging instances around.</p>
</div>
<div class="section" id="the-handler-classes">
<h3>The <code class="docutils literal notranslate"><span class="pre">Handler</span></code> classes<a class="headerlink" href="#the-handler-classes" title="Permalink to this headline"></a></h3>
<p>logging <code class="docutils literal notranslate"><span class="pre">Handler</span></code> s are what actually do the work of, well, handling, the log message.</p>
<p>Formatting it, and actually writing to a file or somehow performing the ‘log’ duty.</p>
<p>There are handlers for writing to files, streams (stdout, stderr), sockets, and nifty things like automaticaly rotating log files.</p>
<p>And, of course, you can make your own.</p>
<p>Each logger can have multiple Handlers</p>
<p>You will most likely use:</p>
<blockquote>
<div><ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">FileHandler</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">StreamHandler</span></code></p></li>
</ul>
</div></blockquote>
<p>The others are documented here.</p>
<p><a class="reference external" href="https://docs.python.org/3/library/logging.handlers.html#module-logging.handlers">https://docs.python.org/3/library/logging.handlers.html#module-logging.handlers</a></p>
</div>
<div class="section" id="the-formatter-classes">
<h3>The <code class="docutils literal notranslate"><span class="pre">Formatter</span></code> classes<a class="headerlink" href="#the-formatter-classes" title="Permalink to this headline"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">Formatters</span></code> are responsible for formatting the log message.</p>
<p>Each log message is stored in a <code class="docutils literal notranslate"><span class="pre">LogRecord</span></code> object, which has a lot of data about the message and where it came from.</p>
<p>So you can use a formatter to add the data you want to your log entry.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">Formatter</span><span class="p">(</span><span class="s1">'</span><span class="si">%(levelname)s</span><span class="s1"> - </span><span class="si">%(module)s</span><span class="s1"> - </span><span class="si">%(message)s</span><span class="s1">'</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">levelname</span></code> is the “level” of the log message: debug, warning, etc. <code class="docutils literal notranslate"><span class="pre">module</span></code> is the name of the module the message came from. <code class="docutils literal notranslate"><span class="pre">message</span></code> is the message itself.</p>
<p>There are lots of other options:</p>
<p><a class="reference external" href="https://docs.python.org/3/library/logging.html#logrecord-attributes">https://docs.python.org/3/library/logging.html#logrecord-attributes</a></p>
<p>Each <code class="docutils literal notranslate"><span class="pre">Handler</span></code> can have its own <code class="docutils literal notranslate"><span class="pre">Formatter</span></code></p>
</div>
<div class="section" id="the-filter-classes">
<h3>The Filter classes<a class="headerlink" href="#the-filter-classes" title="Permalink to this headline"></a></h3>
<p>Each <code class="docutils literal notranslate"><span class="pre">Logger</span></code> can have a <code class="docutils literal notranslate"><span class="pre">Filter</span></code> object.</p>
<p><code class="docutils literal notranslate"><span class="pre">Filters</span></code> determine which messages will be handled by a given logger, and which pass on to other loggers up the hierarchy.</p>
<p>They can do very flexible filtering based on where the message came from, etc.</p>
<p>But only really needed for complex systems:</p>
<p>Loggers filter by “level” by default – which is enough for most uses.</p>
</div>
<div class="section" id="basic-logging-usage">
<h3>Basic logging usage<a class="headerlink" href="#basic-logging-usage" title="Permalink to this headline"></a></h3>
<p>As you can see from the above – the logging system is a complex nest of classes that can be configured and mixed and matched in complex ways.</p>
<p>The system was ported from Java – can you tell?</p>
<p>However, the module provides a Pythonic API for common usage: the <code class="docutils literal notranslate"><span class="pre">logging.basicConfig()</span></code> function.</p>
<p>Example:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><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">filename</span><span class="o">=</span><span class="s1">'example.log'</span><span class="p">,</span>
<span class="n">filemode</span><span class="o">=</span><span class="s1">'w'</span><span class="p">,</span>
<span class="nb">format</span><span class="o">=</span><span class="s1">'</span><span class="si">%(asctime)s</span><span class="s1"> </span><span class="si">%(message)s</span><span class="s1">'</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>
</pre></div>
</div>
<p>This creates a “root” logger, and sets it up with:</p>
<ul>
<li><p>a <code class="docutils literal notranslate"><span class="pre">FileHandler</span></code> with the given filename and mode</p>
<blockquote>
<div><ul class="simple">
<li><p>The mode is the file opening mode: ‘w’ to clobber and make a new file each time, ‘a’ to append to an existing file</p></li>
</ul>
</div></blockquote>
</li>
<li><p>sets up the handler to use the provided format string</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">asctime</span></code> provides a datetime stamp (you can specify a format for that, too)</p></li>
</ul>
</li>
<li><p>sets the level to debug – so all messages will get logged.</p></li>
</ul>
</div>
<div class="section" id="what-does-basicconfig-do-for-you">
<h3>What does <code class="docutils literal notranslate"><span class="pre">basicConfig</span></code> do for you?<a class="headerlink" href="#what-does-basicconfig-do-for-you" title="Permalink to this headline"></a></h3>
<p>A LOT!</p>
<p>If you were to do this by hand:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">filename</span> <span class="o">=</span> <span class="s1">'example.log'</span>
<span class="n">filemode</span> <span class="o">=</span> <span class="s1">'w'</span>
<span class="n">handler</span> <span class="o">=</span> <span class="n">logger</span><span class="o">.</span><span class="n">FileHandler</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
<span class="n">format_str</span> <span class="o">=</span> <span class="s1">'</span><span class="si">%(asctime)s</span><span class="s1"> </span><span class="si">%(message)s</span><span class="s1">'</span>
<span class="n">fmt</span> <span class="o">=</span> <span class="n">logger</span><span class="o">.</span><span class="n">Formatter</span><span class="p">(</span><span class="n">format_str</span><span class="p">)</span>
<span class="n">handler</span><span class="o">.</span><span class="n">setFormatter</span><span class="p">(</span><span class="n">fmt</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">root</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">root</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">EBUG</span><span class="p">)</span>
</pre></div>
</div>
<p>Wouldn’t that be fun?</p>
</div>
<div class="section" id="a-more-complex-logging-setup">
<h3>A more complex logging setup<a class="headerlink" href="#a-more-complex-logging-setup" title="Permalink to this headline"></a></h3>
<p>See:</p>
<p><code class="docutils literal notranslate"><span class="pre">examples/logging/example.py</span></code></p>
<p>In there, a logging system is set up that logs to a file, and also the console.</p>
<p>It calls a fake “application” that does things in random order, logging as it goes…</p>
</div>
<div class="section" id="references">
<h3>References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h3>
<p>The logging system is very powerful and flexible.</p>
<p>And frankly, not as clean and Pythonic as it could be…</p>
<p>So it’s pretty tricky to figure out.</p>
<p>I highly recommend the cookbook to get beyond the basics:</p>
<p><a class="reference external" href="https://docs.python.org/3/howto/logging-cookbook.html">https://docs.python.org/3/howto/logging-cookbook.html</a></p>
<p>Also these:</p>
<p><a class="reference external" href="http://atlee.ca/blog/posts/diving-into-python-logging.html">http://atlee.ca/blog/posts/diving-into-python-logging.html</a></p>
<p><a class="reference external" href="http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python">http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python</a></p>
</div>
</div>
</div>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="../exercises/mailroom/mailroom-meta.html" class="btn btn-neutral float-left" title="Mailroom – metaprogramming it!" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="Debugging.html" class="btn btn-neutral float-right" title="Debugging" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>© Copyright 2020, University of Washington, Natasha Aleksandrova, Christopher Barker, Brian Dorsey, Cris Ewing, Christy Heaton, Jon Jacky, Maria McKinley, Andy Miles, Rick Riehle, Joseph Schilz, Joseph Sheedy, Hosung Song. Creative Commons Attribution-ShareAlike 4.0 license.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>