当前行为:
DEBUG:package:123 > message with
multiple lines
foo bar
想要的行为:
DEBUG:package:123 > message with
multiple lines
foo bar
DEBUG:package:123
可以有不同的宽度,因此在将消息发送到记录器之前无法调整消息。
当前行为:
DEBUG:package:123 > message with
multiple lines
foo bar
想要的行为:
DEBUG:package:123 > message with
multiple lines
foo bar
DEBUG:package:123
可以有不同的宽度,因此在将消息发送到记录器之前无法调整消息。
现有答案很好地回答了缩进部分。但是与format
原来exec_info
的.stack_info
logging.Formatter
以下实现基于simonzack 的回答,并重用原始格式化程序以尽量减少副作用。
[edit 2021-11] 它还通过对格式化消息进行后处理而不是对其进行预处理来正确处理格式化值
class MultiLineFormatter(logging.Formatter):
"""Multi-line formatter."""
def get_header_length(self, record):
"""Get the header length of a given record."""
return len(super().format(logging.LogRecord(
name=record.name,
level=record.levelno,
pathname=record.pathname,
lineno=record.lineno,
msg='', args=(), exc_info=None
)))
def format(self, record):
"""Format a record with added indentation."""
indent = ' ' * self.get_header_length(record)
head, *trailing = super().format(record).splitlines(True)
return head + ''.join(indent + line for line in trailing)
这是 aiven 的版本,它更加现代化和灵活。
class MultiLineFormatter(logging.Formatter):
def format(self, record):
message = record.msg
record.msg = ''
header = super().format(record)
msg = textwrap.indent(message, ' ' * len(header)).lstrip()
record.msg = message
return header + msg
为了使用这个:
formatter = MultiLineFormatter(
fmt='%(asctime)s %(levelname)-8s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
)
log_handler = logging.StreamHandler()
log_handler.setFormatter(formatter)
以自定义格式化程序结束,而 fmt 字符串中没有消息:
import textwrap
class Formatter(logging.Formatter):
def __init__(self):
super(Formatter, self).__init__(fmt="%(levelname)-8s %(name)20s:%(lineno)-3d > ")
def format(self, record):
header = super(Formatter, self).format(record)
msg = textwrap.indent(record.message, ' ' * len(header)).strip()
return header + msg
修改 aiven 的版本以正常工作。
class Formatter(logging.Formatter):
def __init__(self, format_str):
super(Formatter, self).__init__(fmt=format_str)
def format(self, record):
message = record.msg
record.msg = ''
header = super(Formatter, self).format(record)
msg = textwrap.indent(message, ' ' * len(header)).strip()
record.msg = message
return header + msg