Les réponses existantes ont bien répondu à la question de l'indentation. Mais la nouvelle format
n'a pas traité d'autres champs (par ex. exec_info
, stack_info
) par rapport à l'original logging.Formatter
.
La mise en œuvre ci-dessous est basée sur Réponse de simonzack et réutilise le formateur d'origine pour minimiser les effets secondaires.
class MultiLineFormatter(logging.Formatter):
"""Multi-line formatter."""
def get_header_length(self, record):
"""Get the header length of a given record."""
record = copy.copy(record)
record.msg = ''
record.exc_info = None
record.exc_text = None
record.stack_info = None
header = super().format(record)
return len(header)
def format(self, record):
"""Format a record with added indentation."""
message = record.msg
# For now we only indent string typed messages
# Other message types like list or bytes won't be touched
if isinstance(message, str):
msgs = message.splitlines(True)
if len(msgs) > 1:
header_len = self.get_header_length(record)
# Indent lines (except the first line)
indented_message = msgs[0] + ''.join(map(
lambda m: ' ' * header_len + m if m != '\n' else m, msgs[1:]))
# Use the original formatter since it handles exceptions well
record.msg = indented_message
formatted_text = super().format(record)
# Revert to keep the msg field untouched
# As other modules may capture the log for further processing
record.msg = message
return formatted_text
return super().format(record)