@@ -4078,6 +4078,68 @@ lines. With this approach, you get better output:
40784078 WARNING:demo: 1/0
40794079 WARNING:demo:ZeroDivisionError: division by zero
40804080
4081+ How to uniformly handle newlines in logging output
4082+ --------------------------------------------------
4083+
4084+ Usually, messages that are logged (say to console or file) consist of a single
4085+ line of text. However, sometimes there is a need to handle messages with
4086+ multiple lines - whether because a logging format string contains newlines, or
4087+ logged data contains newlines. If you want to handle such messages uniformly, so
4088+ that each line in the logged message appears uniformly formatted as if it was
4089+ logged separately, you can do this using a handler mixin, as in the following
4090+ snippet:
4091+
4092+ .. code-block :: python
4093+
4094+ # Assume this is in a module mymixins.py
4095+ import copy
4096+
4097+ class MultilineMixin :
4098+ def emit (self , record ):
4099+ s = record.getMessage()
4100+ if ' \n ' not in s:
4101+ super ().emit(record)
4102+ else :
4103+ lines = s.splitlines()
4104+ rec = copy.copy(record)
4105+ rec.args = None
4106+ for line in lines:
4107+ rec.msg = line
4108+ super ().emit(rec)
4109+
4110+ You can use the mixin as in the following script:
4111+
4112+ .. code-block :: python
4113+
4114+ import logging
4115+
4116+ from mymixins import MultilineMixin
4117+
4118+ logger = logging.getLogger(__name__ )
4119+
4120+ class StreamHandler (MultilineMixin , logging .StreamHandler ):
4121+ pass
4122+
4123+ if __name__ == ' __main__' :
4124+ logging.basicConfig(level = logging.DEBUG , format = ' %(asctime)s %(levelname)-9s %(message)s ' ,
4125+ handlers = [StreamHandler()])
4126+ logger.debug(' Single line' )
4127+ logger.debug(' Multiple lines:\n fool me once ...' )
4128+ logger.debug(' Another single line' )
4129+ logger.debug(' Multiple lines:\n %s ' , ' fool me ...\n can\' t get fooled again' )
4130+
4131+ The script, when run, prints something like:
4132+
4133+ .. code-block :: text
4134+
4135+ 2025-07-02 13:54:47,234 DEBUG Single line
4136+ 2025-07-02 13:54:47,234 DEBUG Multiple lines:
4137+ 2025-07-02 13:54:47,234 DEBUG fool me once ...
4138+ 2025-07-02 13:54:47,234 DEBUG Another single line
4139+ 2025-07-02 13:54:47,234 DEBUG Multiple lines:
4140+ 2025-07-02 13:54:47,234 DEBUG fool me ...
4141+ 2025-07-02 13:54:47,234 DEBUG can't get fooled again
4142+
40814143
40824144.. patterns-to-avoid:
40834145
0 commit comments