@@ -4078,6 +4078,68 @@ lines. With this approach, you get better output:
4078
4078
WARNING:demo: 1/0
4079
4079
WARNING:demo:ZeroDivisionError: division by zero
4080
4080
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
+
4081
4143
4082
4144
.. patterns-to-avoid:
4083
4145
0 commit comments