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