mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-94503: Update logging cookbook with an example of uniformly handling newlines in output. (GH-136217)
This commit is contained in:
parent
3e849d75f4
commit
d05423a90c
1 changed files with 62 additions and 0 deletions
|
@ -4078,6 +4078,68 @@ lines. With this approach, you get better output:
|
||||||
WARNING:demo: 1/0
|
WARNING:demo: 1/0
|
||||||
WARNING:demo:ZeroDivisionError: division by zero
|
WARNING:demo:ZeroDivisionError: division by zero
|
||||||
|
|
||||||
|
How to uniformly handle newlines in logging output
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Usually, messages that are logged (say to console or file) consist of a single
|
||||||
|
line of text. However, sometimes there is a need to handle messages with
|
||||||
|
multiple lines - whether because a logging format string contains newlines, or
|
||||||
|
logged data contains newlines. If you want to handle such messages uniformly, so
|
||||||
|
that each line in the logged message appears uniformly formatted as if it was
|
||||||
|
logged separately, you can do this using a handler mixin, as in the following
|
||||||
|
snippet:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
# Assume this is in a module mymixins.py
|
||||||
|
import copy
|
||||||
|
|
||||||
|
class MultilineMixin:
|
||||||
|
def emit(self, record):
|
||||||
|
s = record.getMessage()
|
||||||
|
if '\n' not in s:
|
||||||
|
super().emit(record)
|
||||||
|
else:
|
||||||
|
lines = s.splitlines()
|
||||||
|
rec = copy.copy(record)
|
||||||
|
rec.args = None
|
||||||
|
for line in lines:
|
||||||
|
rec.msg = line
|
||||||
|
super().emit(rec)
|
||||||
|
|
||||||
|
You can use the mixin as in the following script:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from mymixins import MultilineMixin
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class StreamHandler(MultilineMixin, logging.StreamHandler):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-9s %(message)s',
|
||||||
|
handlers = [StreamHandler()])
|
||||||
|
logger.debug('Single line')
|
||||||
|
logger.debug('Multiple lines:\nfool me once ...')
|
||||||
|
logger.debug('Another single line')
|
||||||
|
logger.debug('Multiple lines:\n%s', 'fool me ...\ncan\'t get fooled again')
|
||||||
|
|
||||||
|
The script, when run, prints something like:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
2025-07-02 13:54:47,234 DEBUG Single line
|
||||||
|
2025-07-02 13:54:47,234 DEBUG Multiple lines:
|
||||||
|
2025-07-02 13:54:47,234 DEBUG fool me once ...
|
||||||
|
2025-07-02 13:54:47,234 DEBUG Another single line
|
||||||
|
2025-07-02 13:54:47,234 DEBUG Multiple lines:
|
||||||
|
2025-07-02 13:54:47,234 DEBUG fool me ...
|
||||||
|
2025-07-02 13:54:47,234 DEBUG can't get fooled again
|
||||||
|
|
||||||
|
|
||||||
.. patterns-to-avoid:
|
.. patterns-to-avoid:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue