mirror of
https://github.com/python/cpython.git
synced 2025-07-07 11:25:30 +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: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:
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue