summaryrefslogtreecommitdiffstats
path: root/Doc
diff options
context:
space:
mode:
authorVinay Sajip <vinay_sajip@yahoo.co.uk>2024-04-04 12:14:44 (GMT)
committerGitHub <noreply@github.com>2024-04-04 12:14:44 (GMT)
commitdf912c913a3d94995b379f1e19fe0a79acab6169 (patch)
tree3b909c1c5bf63ea0d9908e904a896ddf23a9b645 /Doc
parentb32789ccb91bbe43e88193f68b1364a8da6d9866 (diff)
downloadcpython-df912c913a3d94995b379f1e19fe0a79acab6169.zip
cpython-df912c913a3d94995b379f1e19fe0a79acab6169.tar.gz
cpython-df912c913a3d94995b379f1e19fe0a79acab6169.tar.bz2
[doc] Update logging documentation to improve grammar and elucidate an example. (GH-117541)
Diffstat (limited to 'Doc')
-rw-r--r--Doc/howto/logging-cookbook.rst68
-rw-r--r--Doc/library/logging.rst15
2 files changed, 72 insertions, 11 deletions
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index d8ebeab..61723bc 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -1915,7 +1915,7 @@ In a similar way to the above section, we can implement a listener and handler
using `pynng <https://pypi.org/project/pynng/>`_, which is a Python binding to
`NNG <https://nng.nanomsg.org/>`_, billed as a spiritual successor to ZeroMQ.
The following snippets illustrate -- you can test them in an environment which has
-``pynng`` installed. Juat for variety, we present the listener first.
+``pynng`` installed. Just for variety, we present the listener first.
Subclass ``QueueListener``
@@ -1923,6 +1923,7 @@ Subclass ``QueueListener``
.. code-block:: python
+ # listener.py
import json
import logging
import logging.handlers
@@ -1955,7 +1956,7 @@ Subclass ``QueueListener``
break
except pynng.Timeout:
pass
- except pynng.Closed: # sometimes hit when you hit Ctrl-C
+ except pynng.Closed: # sometimes happens when you hit Ctrl-C
break
if data is None:
return None
@@ -1988,6 +1989,7 @@ Subclass ``QueueHandler``
.. code-block:: python
+ # sender.py
import json
import logging
import logging.handlers
@@ -2015,9 +2017,10 @@ Subclass ``QueueHandler``
logging.getLogger('pynng').propagate = False
handler = NNGSocketHandler(DEFAULT_ADDR)
+ # Make sure the process ID is in the output
logging.basicConfig(level=logging.DEBUG,
handlers=[logging.StreamHandler(), handler],
- format='%(levelname)-8s %(name)10s %(message)s')
+ format='%(levelname)-8s %(name)10s %(process)6s %(message)s')
levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR,
logging.CRITICAL)
logger_names = ('myapp', 'myapp.lib1', 'myapp.lib2')
@@ -2031,7 +2034,64 @@ Subclass ``QueueHandler``
delay = random.random() * 2 + 0.5
time.sleep(delay)
-You can run the above two snippets in separate command shells.
+You can run the above two snippets in separate command shells. If we run the
+listener in one shell and run the sender in two separate shells, we should see
+something like the following. In the first sender shell:
+
+.. code-block:: console
+
+ $ python sender.py
+ DEBUG myapp 613 Message no. 1
+ WARNING myapp.lib2 613 Message no. 2
+ CRITICAL myapp.lib2 613 Message no. 3
+ WARNING myapp.lib2 613 Message no. 4
+ CRITICAL myapp.lib1 613 Message no. 5
+ DEBUG myapp 613 Message no. 6
+ CRITICAL myapp.lib1 613 Message no. 7
+ INFO myapp.lib1 613 Message no. 8
+ (and so on)
+
+In the second sender shell:
+
+.. code-block:: console
+
+ $ python sender.py
+ INFO myapp.lib2 657 Message no. 1
+ CRITICAL myapp.lib2 657 Message no. 2
+ CRITICAL myapp 657 Message no. 3
+ CRITICAL myapp.lib1 657 Message no. 4
+ INFO myapp.lib1 657 Message no. 5
+ WARNING myapp.lib2 657 Message no. 6
+ CRITICAL myapp 657 Message no. 7
+ DEBUG myapp.lib1 657 Message no. 8
+ (and so on)
+
+In the listener shell:
+
+.. code-block:: console
+
+ $ python listener.py
+ Press Ctrl-C to stop.
+ DEBUG myapp 613 Message no. 1
+ WARNING myapp.lib2 613 Message no. 2
+ INFO myapp.lib2 657 Message no. 1
+ CRITICAL myapp.lib2 613 Message no. 3
+ CRITICAL myapp.lib2 657 Message no. 2
+ CRITICAL myapp 657 Message no. 3
+ WARNING myapp.lib2 613 Message no. 4
+ CRITICAL myapp.lib1 613 Message no. 5
+ CRITICAL myapp.lib1 657 Message no. 4
+ INFO myapp.lib1 657 Message no. 5
+ DEBUG myapp 613 Message no. 6
+ WARNING myapp.lib2 657 Message no. 6
+ CRITICAL myapp 657 Message no. 7
+ CRITICAL myapp.lib1 613 Message no. 7
+ INFO myapp.lib1 613 Message no. 8
+ DEBUG myapp.lib1 657 Message no. 8
+ (and so on)
+
+As you can see, the logging from the two sender processes is interleaved in the
+listener's output.
An example dictionary-based configuration
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index 4e7d18b..7816cc2 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -63,12 +63,13 @@ If you run *myapp.py*, you should see this in *myapp.log*:
INFO:mylib:Doing something
INFO:__main__:Finished
-The key features of this idiomatic usage is that the majority of code is simply
+The key feature of this idiomatic usage is that the majority of code is simply
creating a module level logger with ``getLogger(__name__)``, and using that
-logger to do any needed logging. This is concise while allowing downstream code
-fine grained control if needed. Logged messages to the module-level logger get
-forwarded up to handlers of loggers in higher-level modules, all the way up to
-the root logger; for this reason this approach is known as hierarchical logging.
+logger to do any needed logging. This is concise, while allowing downstream
+code fine-grained control if needed. Logged messages to the module-level logger
+get forwarded to handlers of loggers in higher-level modules, all the way up to
+the highest-level logger known as the root logger; this approach is known as
+hierarchical logging.
For logging to be useful, it needs to be configured: setting the levels and
destinations for each logger, potentially changing how specific modules log,
@@ -82,8 +83,8 @@ The module provides a lot of functionality and flexibility. If you are
unfamiliar with logging, the best way to get to grips with it is to view the
tutorials (**see the links above and on the right**).
-The basic classes defined by the module, together with their functions, are
-listed below.
+The basic classes defined by the module, together with their attributes and
+methods, are listed in the sections below.
* Loggers expose the interface that application code directly uses.
* Handlers send the log records (created by loggers) to the appropriate