diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2024-04-04 12:14:44 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-04 12:14:44 (GMT) |
commit | df912c913a3d94995b379f1e19fe0a79acab6169 (patch) | |
tree | 3b909c1c5bf63ea0d9908e904a896ddf23a9b645 /Doc | |
parent | b32789ccb91bbe43e88193f68b1364a8da6d9866 (diff) | |
download | cpython-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.rst | 68 | ||||
-rw-r--r-- | Doc/library/logging.rst | 15 |
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 |