]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] [doc] Update logging documentation to improve grammar and elucidate an example...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 4 Apr 2024 13:19:10 +0000 (15:19 +0200)
committerGitHub <noreply@github.com>
Thu, 4 Apr 2024 13:19:10 +0000 (14:19 +0100)
(cherry picked from commit df912c913a3d94995b379f1e19fe0a79acab6169)

Doc/howto/logging-cookbook.rst
Doc/library/logging.rst

index fe13a7cbe8bcf91d42e1973b3a14653d079add67..d7b282a0de8aa67ef04fcdd1932c402201a29b22 100644 (file)
@@ -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
index 2bfa8a133dffaec08d613e022b56aa0dbfca2f6c..103bbcf51ad947e65757bbde90f4e925f8356aec 100644 (file)
@@ -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