logging: Improve formatting of multiline message (#5312)
logging: Improve formatting of multiline message
This commit is contained in:
commit
c8d23c206b
|
@ -0,0 +1 @@
|
||||||
|
Improved formatting of multiline log messages in python3.
|
|
@ -77,6 +77,36 @@ class ColoredLevelFormatter(logging.Formatter):
|
||||||
return super(ColoredLevelFormatter, self).format(record)
|
return super(ColoredLevelFormatter, self).format(record)
|
||||||
|
|
||||||
|
|
||||||
|
if not six.PY2:
|
||||||
|
# Formatter classes don't support format styles in PY2
|
||||||
|
|
||||||
|
class PercentStyleMultiline(logging.PercentStyle):
|
||||||
|
"""A logging style with special support for multiline messages.
|
||||||
|
|
||||||
|
If the message of a record consists of multiple lines, this style
|
||||||
|
formats the message as if each line were logged separately.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _update_message(record_dict, message):
|
||||||
|
tmp = record_dict.copy()
|
||||||
|
tmp["message"] = message
|
||||||
|
return tmp
|
||||||
|
|
||||||
|
def format(self, record):
|
||||||
|
if "\n" in record.message:
|
||||||
|
lines = record.message.splitlines()
|
||||||
|
formatted = self._fmt % self._update_message(record.__dict__, lines[0])
|
||||||
|
# TODO optimize this by introducing an option that tells the
|
||||||
|
# logging framework that the indentation doesn't
|
||||||
|
# change. This allows to compute the indentation only once.
|
||||||
|
indentation = _remove_ansi_escape_sequences(formatted).find(lines[0])
|
||||||
|
lines[0] = formatted
|
||||||
|
return ("\n" + " " * indentation).join(lines)
|
||||||
|
else:
|
||||||
|
return self._fmt % record.__dict__
|
||||||
|
|
||||||
|
|
||||||
def get_option_ini(config, *names):
|
def get_option_ini(config, *names):
|
||||||
for name in names:
|
for name in names:
|
||||||
ret = config.getoption(name) # 'default' arg won't work as expected
|
ret = config.getoption(name) # 'default' arg won't work as expected
|
||||||
|
@ -444,6 +474,9 @@ class LoggingPlugin(object):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
formatter = logging.Formatter(log_format, log_date_format)
|
formatter = logging.Formatter(log_format, log_date_format)
|
||||||
|
|
||||||
|
if not six.PY2:
|
||||||
|
formatter._style = PercentStyleMultiline(formatter._style._fmt)
|
||||||
return formatter
|
return formatter
|
||||||
|
|
||||||
def _setup_cli_logging(self):
|
def _setup_cli_logging(self):
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import py.io
|
import py.io
|
||||||
|
import six
|
||||||
|
|
||||||
|
import pytest
|
||||||
from _pytest.logging import ColoredLevelFormatter
|
from _pytest.logging import ColoredLevelFormatter
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,3 +37,31 @@ def test_coloredlogformatter():
|
||||||
formatter = ColoredLevelFormatter(tw, logfmt)
|
formatter = ColoredLevelFormatter(tw, logfmt)
|
||||||
output = formatter.format(record)
|
output = formatter.format(record)
|
||||||
assert output == ("dummypath 10 INFO Test Message")
|
assert output == ("dummypath 10 INFO Test Message")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
six.PY2, reason="Formatter classes don't support format styles in PY2"
|
||||||
|
)
|
||||||
|
def test_multiline_message():
|
||||||
|
from _pytest.logging import PercentStyleMultiline
|
||||||
|
|
||||||
|
logfmt = "%(filename)-25s %(lineno)4d %(levelname)-8s %(message)s"
|
||||||
|
|
||||||
|
record = logging.LogRecord(
|
||||||
|
name="dummy",
|
||||||
|
level=logging.INFO,
|
||||||
|
pathname="dummypath",
|
||||||
|
lineno=10,
|
||||||
|
msg="Test Message line1\nline2",
|
||||||
|
args=(),
|
||||||
|
exc_info=False,
|
||||||
|
)
|
||||||
|
# this is called by logging.Formatter.format
|
||||||
|
record.message = record.getMessage()
|
||||||
|
|
||||||
|
style = PercentStyleMultiline(logfmt)
|
||||||
|
output = style.format(record)
|
||||||
|
assert output == (
|
||||||
|
"dummypath 10 INFO Test Message line1\n"
|
||||||
|
" line2"
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue