summaryrefslogtreecommitdiffstats
path: root/Doc/howto
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-10-20 11:53:53 (GMT)
committerGitHub <noreply@github.com>2022-10-20 11:53:53 (GMT)
commit3f040bc8e4edef0940c71e4609bd9785b02d0f9e (patch)
tree8363b4fc166037c4fa324c729ffcc0c640acba77 /Doc/howto
parentdddbbd9e3e4e12ed5a805dd4e08953e3332a15ea (diff)
downloadcpython-3f040bc8e4edef0940c71e4609bd9785b02d0f9e.zip
cpython-3f040bc8e4edef0940c71e4609bd9785b02d0f9e.tar.gz
cpython-3f040bc8e4edef0940c71e4609bd9785b02d0f9e.tar.bz2
[3.10] [doc] Improve logging cookbook example. (GH-98481) (GH-98482)
Co-authored-by: Vinay Sajip <vinay_sajip@yahoo.co.uk>
Diffstat (limited to 'Doc/howto')
-rw-r--r--Doc/howto/logging-cookbook.rst65
1 files changed, 65 insertions, 0 deletions
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index d9a1942..22f7aa9 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -3712,6 +3712,71 @@ Of course, these above examples show output according to the format used by
:func:`~logging.basicConfig`, but you can use a different formatter when you
configure logging.
+Note that with the above scheme, you are somewhat at the mercy of buffering and
+the sequence of write calls which you are intercepting. For example, with the
+definition of ``LoggerWriter`` above, if you have the snippet
+
+.. code-block:: python
+
+ sys.stderr = LoggerWriter(logger, logging.WARNING)
+ 1 / 0
+
+then running the script results in
+
+.. code-block:: text
+
+ WARNING:demo:Traceback (most recent call last):
+
+ WARNING:demo: File "/home/runner/cookbook-loggerwriter/test.py", line 53, in <module>
+
+ WARNING:demo:
+ WARNING:demo:main()
+ WARNING:demo: File "/home/runner/cookbook-loggerwriter/test.py", line 49, in main
+
+ WARNING:demo:
+ WARNING:demo:1 / 0
+ WARNING:demo:ZeroDivisionError
+ WARNING:demo::
+ WARNING:demo:division by zero
+
+As you can see, this output isn't ideal. That's because the underlying code
+which writes to ``sys.stderr`` makes mutiple writes, each of which results in a
+separate logged line (for example, the last three lines above). To get around
+this problem, you need to buffer things and only output log lines when newlines
+are seen. Let's use a slghtly better implementation of ``LoggerWriter``:
+
+.. code-block:: python
+
+ class BufferingLoggerWriter(LoggerWriter):
+ def __init__(self, logger, level):
+ super().__init__(logger, level)
+ self.buffer = ''
+
+ def write(self, message):
+ if '\n' not in message:
+ self.buffer += message
+ else:
+ parts = message.split('\n')
+ if self.buffer:
+ s = self.buffer + parts.pop(0)
+ self.logger.log(self.level, s)
+ self.buffer = parts.pop()
+ for part in parts:
+ self.logger.log(self.level, part)
+
+This just buffers up stuff until a newline is seen, and then logs complete
+lines. With this approach, you get better output:
+
+.. code-block:: text
+
+ WARNING:demo:Traceback (most recent call last):
+ WARNING:demo: File "/home/runner/cookbook-loggerwriter/main.py", line 55, in <module>
+ WARNING:demo: main()
+ WARNING:demo: File "/home/runner/cookbook-loggerwriter/main.py", line 52, in main
+ WARNING:demo: 1/0
+ WARNING:demo:ZeroDivisionError: division by zero
+
+
.. patterns-to-avoid:
Patterns to avoid