Skip to content

Commit 6f4163f

Browse files
committed
Changes to logging intro documentation
1 parent b96b344 commit 6f4163f

File tree

2 files changed

+78
-76
lines changed

2 files changed

+78
-76
lines changed

Doc/howto/logging.rst

Lines changed: 35 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ When to use logging
2626
^^^^^^^^^^^^^^^^^^^
2727

2828
Logging provides a set of convenience functions for simple logging usage. These
29-
are :func:`debug`, :func:`info`, :func:`warning`, :func:`error` and
30-
:func:`critical`. To determine when to use logging, see the table below, which
31-
states, for each of a set of common tasks, the best tool to use for it.
29+
can be accessed by creating a logger via ``logger = getLogger(__name__)``, and
30+
then calling :func:`logger.debug`, :func:`logger.info`, :func:`logger.warning`,
31+
:func:`logger.error` and :func:`logger.critical`. To determine when to use
32+
logging, see the table below, which states, for each of a set of common tasks,
33+
the best tool to use for it.
3234

3335
+-------------------------------------+--------------------------------------+
3436
| Task you want to perform | The best tool for the task |
@@ -37,8 +39,8 @@ states, for each of a set of common tasks, the best tool to use for it.
3739
| usage of a command line script or | |
3840
| program | |
3941
+-------------------------------------+--------------------------------------+
40-
| Report events that occur during | :func:`logging.info` (or |
41-
| normal operation of a program (e.g. | :func:`logging.debug` for very |
42+
| Report events that occur during | :func:`logger.info` (or |
43+
| normal operation of a program (e.g. | :func:`logger.debug` for very |
4244
| for status monitoring or fault | detailed output for diagnostic |
4345
| investigation) | purposes) |
4446
+-------------------------------------+--------------------------------------+
@@ -47,22 +49,22 @@ states, for each of a set of common tasks, the best tool to use for it.
4749
| | the client application should be |
4850
| | modified to eliminate the warning |
4951
| | |
50-
| | :func:`logging.warning` if there is |
52+
| | :func:`logger.warning` if there is |
5153
| | nothing the client application can do|
5254
| | about the situation, but the event |
5355
| | should still be noted |
5456
+-------------------------------------+--------------------------------------+
5557
| Report an error regarding a | Raise an exception |
5658
| particular runtime event | |
5759
+-------------------------------------+--------------------------------------+
58-
| Report suppression of an error | :func:`logging.error`, |
59-
| without raising an exception (e.g. | :func:`logging.exception` or |
60-
| error handler in a long-running | :func:`logging.critical` as |
60+
| Report suppression of an error | :func:`logger.error`, |
61+
| without raising an exception (e.g. | :func:`logger.exception` or |
62+
| error handler in a long-running | :func:`logger.critical` as |
6163
| server process) | appropriate for the specific error |
6264
| | and application domain |
6365
+-------------------------------------+--------------------------------------+
6466

65-
The logging functions are named after the level or severity of the events
67+
The functions are named after the level or severity of the events
6668
they are used to track. The standard levels and their applicability are
6769
described below (in increasing order of severity):
6870

@@ -116,12 +118,18 @@ If you type these lines into a script and run it, you'll see:
116118
WARNING:root:Watch out!
117119
118120
printed out on the console. The ``INFO`` message doesn't appear because the
119-
default level is ``WARNING``. The printed message includes the indication of
120-
the level and the description of the event provided in the logging call, i.e.
121-
'Watch out!'. Don't worry about the 'root' part for now: it will be explained
122-
later. The actual output can be formatted quite flexibly if you need that;
123-
formatting options will also be explained later.
124-
121+
default level is ``WARNING``. The printed message includes the indication of the
122+
level and the description of the event provided in the logging call, i.e.
123+
'Watch out!'. The actual output can be formatted quite flexibly if you need
124+
that; formatting options will also be explained later.
125+
126+
Notice that in this example, we use functions directly on the ``logging``
127+
module, like ``logging.debug``, rather than creating a logger and calling
128+
functions on it. These functions operation on the root logger, but can be useful
129+
as they will call ``basicConfig`` for you if it has not been called yet, like in
130+
this example. In larger programs you'll usually want to control this call
131+
explicitly however, so for that reason as well as others, it's better to explicitly
132+
create loggers and call their member functions.
125133

126134
Logging to a file
127135
^^^^^^^^^^^^^^^^^
@@ -131,11 +139,12 @@ look at that next. Be sure to try the following in a newly started Python
131139
interpreter, and don't just continue from the session described above::
132140

133141
import logging
142+
logger = logging.getLogger(__name__)
134143
logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG)
135-
logging.debug('This message should go to the log file')
136-
logging.info('So should this')
137-
logging.warning('And this, too')
138-
logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
144+
logger.debug('This message should go to the log file')
145+
logger.info('So should this')
146+
logger.warning('And this, too')
147+
logger.error('And non-ASCII stuff, too, like Øresund and Malmö')
139148

140149
.. versionchanged:: 3.9
141150
The *encoding* argument was added. In earlier Python versions, or if not
@@ -149,10 +158,10 @@ messages:
149158

150159
.. code-block:: none
151160
152-
DEBUG:root:This message should go to the log file
153-
INFO:root:So should this
154-
WARNING:root:And this, too
155-
ERROR:root:And non-ASCII stuff, too, like Øresund and Malmö
161+
DEBUG:__main__:This message should go to the log file
162+
INFO:__main__:So should this
163+
WARNING:__main__:And this, too
164+
ERROR:__main__:And non-ASCII stuff, too, like Øresund and Malmö
156165
157166
This example also shows how you can set the logging level which acts as the
158167
threshold for tracking. In this case, because we set the threshold to
@@ -182,10 +191,8 @@ following example::
182191
logging.basicConfig(level=numeric_level, ...)
183192

184193
The call to :func:`basicConfig` should come *before* any calls to
185-
:func:`debug`, :func:`info`, etc. Otherwise, those functions will call
186-
:func:`basicConfig` for you with the default options. As it's intended as a
187-
one-off simple configuration facility, only the first call will actually do
188-
anything: subsequent calls are effectively no-ops.
194+
:func:`logger.debug`, :func:`logger.info`, etc. Otherwise, that logging
195+
will not be handled.
189196

190197
If you run the above script several times, the messages from successive runs
191198
are appended to the file *example.log*. If you want each run to start afresh,
@@ -198,50 +205,6 @@ The output will be the same as before, but the log file is no longer appended
198205
to, so the messages from earlier runs are lost.
199206

200207

201-
Logging from multiple modules
202-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
203-
204-
If your program consists of multiple modules, here's an example of how you
205-
could organize logging in it::
206-
207-
# myapp.py
208-
import logging
209-
import mylib
210-
211-
def main():
212-
logging.basicConfig(filename='myapp.log', level=logging.INFO)
213-
logging.info('Started')
214-
mylib.do_something()
215-
logging.info('Finished')
216-
217-
if __name__ == '__main__':
218-
main()
219-
220-
::
221-
222-
# mylib.py
223-
import logging
224-
225-
def do_something():
226-
logging.info('Doing something')
227-
228-
If you run *myapp.py*, you should see this in *myapp.log*:
229-
230-
.. code-block:: none
231-
232-
INFO:root:Started
233-
INFO:root:Doing something
234-
INFO:root:Finished
235-
236-
which is hopefully what you were expecting to see. You can generalize this to
237-
multiple modules, using the pattern in *mylib.py*. Note that for this simple
238-
usage pattern, you won't know, by looking in the log file, *where* in your
239-
application your messages came from, apart from looking at the event
240-
description. If you want to track the location of your messages, you'll need
241-
to refer to the documentation beyond the tutorial level -- see
242-
:ref:`logging-advanced-tutorial`.
243-
244-
245208
Logging variable data
246209
^^^^^^^^^^^^^^^^^^^^^
247210

Doc/library/logging.rst

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,52 @@ is that all Python modules can participate in logging, so your application log
3030
can include your own messages integrated with messages from third-party
3131
modules.
3232

33-
The simplest example:
33+
Here's a simple example of idiomatic usage: ::
34+
35+
# myapp.py
36+
import logging
37+
import mylib
38+
logger = logging.getLogger(__name__)
39+
40+
def main():
41+
logging.basicConfig(filename='myapp.log', level=logging.INFO)
42+
logger.info('Started')
43+
mylib.do_something()
44+
logger.info('Finished')
45+
46+
if __name__ == '__main__':
47+
main()
48+
49+
::
50+
51+
# mylib.py
52+
import logging
53+
logger = logging.getLogger(__name__)
54+
55+
def do_something():
56+
logger.info('Doing something')
57+
58+
If you run *myapp.py*, you should see this in *myapp.log*:
3459

3560
.. code-block:: none
3661
37-
>>> import logging
38-
>>> logging.warning('Watch out!')
39-
WARNING:root:Watch out!
62+
INFO:__main__:Started
63+
INFO:mylib:Doing something
64+
INFO:__main__:Finished
65+
66+
The key features of this idiomatic usage is that the majority of code is simply
67+
creating a module level logger with ``getLogger``, and using that logger to do
68+
any needed logging. This is concise while allowing downstream code fine grained
69+
control if needed. Logged messages to the module lever logger get forwarded "up"
70+
the module hierarchy; for this reason this approach is known as hierarchical
71+
logging.
72+
73+
Then, very specific pieces of code actually perform logger
74+
configuration: setting the level, destinations, potentially changing how specific
75+
modules log, and so on, often based on arguments or configuration. In most cases,
76+
like the one above, only the root logger needs to be so configured, since all the
77+
module level loggers eventually forward their messages to it. ``basicConfig``
78+
provides a quick way to configure the root logger that handles many use cases.
4079

4180
The module provides a lot of functionality and flexibility. If you are
4281
unfamiliar with logging, the best way to get to grips with it is to view the

0 commit comments

Comments
 (0)