logging: Make it possible to add cli colors to custom log levels
Closes #8803 PR #8804 Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com> Co-authored-by: Terje Runde <terje.runde@flir.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
df033f3ab1
commit
2439729413
1
AUTHORS
1
AUTHORS
|
@ -309,6 +309,7 @@ Tanvi Mehta
|
|||
Tarcisio Fischer
|
||||
Tareq Alayan
|
||||
Ted Xiao
|
||||
Terje Runde
|
||||
Thomas Grainger
|
||||
Thomas Hisch
|
||||
Tim Hoffmann
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
It is now possible to add colors to custom log levels on cli log.
|
||||
|
||||
By using :func:`add_color_level <_pytest.logging.add_color_level` from a ``pytest_configure`` hook, colors can be added::
|
||||
|
||||
logging_plugin = config.pluginmanager.get_plugin('logging-plugin')
|
||||
logging_plugin.log_cli_handler.formatter.add_color_level(logging.INFO, 'cyan')
|
||||
logging_plugin.log_cli_handler.formatter.add_color_level(logging.SPAM, 'blue')
|
||||
|
||||
See :ref:`log_colors` for more information.
|
|
@ -219,6 +219,30 @@ option names are:
|
|||
You can call ``set_log_path()`` to customize the log_file path dynamically. This functionality
|
||||
is considered **experimental**.
|
||||
|
||||
.. _log_colors:
|
||||
|
||||
Customizing Colors
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Log levels are colored if colored terminal output is enabled. Changing
|
||||
from default colors or putting color on custom log levels is supported
|
||||
through ``add_color_level()``. Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.hookimpl
|
||||
def pytest_configure(config):
|
||||
logging_plugin = config.pluginmanager.get_plugin("logging-plugin")
|
||||
|
||||
# Change color on existing log level
|
||||
logging_plugin.log_cli_handler.formatter.add_color_level(logging.INFO, "cyan")
|
||||
|
||||
# Add color to a custom log level (a custom log level `SPAM` is already set up)
|
||||
logging_plugin.log_cli_handler.formatter.add_color_level(logging.SPAM, "blue")
|
||||
.. warning::
|
||||
|
||||
This feature and its API are considered **experimental** and might change
|
||||
between releases without a deprecation notice.
|
||||
.. _log_release_notes:
|
||||
|
||||
Release notes
|
||||
|
|
|
@ -63,28 +63,43 @@ class ColoredLevelFormatter(logging.Formatter):
|
|||
|
||||
def __init__(self, terminalwriter: TerminalWriter, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self._terminalwriter = terminalwriter
|
||||
self._original_fmt = self._style._fmt
|
||||
self._level_to_fmt_mapping: Dict[int, str] = {}
|
||||
|
||||
for level, color_opts in self.LOGLEVEL_COLOROPTS.items():
|
||||
self.add_color_level(level, *color_opts)
|
||||
|
||||
def add_color_level(self, level: int, *color_opts: str) -> None:
|
||||
"""Add or update color opts for a log level.
|
||||
|
||||
:param level:
|
||||
Log level to apply a style to, e.g. ``logging.INFO``.
|
||||
:param color_opts:
|
||||
ANSI escape sequence color options. Capitalized colors indicates
|
||||
background color, i.e. ``'green', 'Yellow', 'bold'`` will give bold
|
||||
green text on yellow background.
|
||||
|
||||
.. warning::
|
||||
This is an experimental API.
|
||||
"""
|
||||
|
||||
assert self._fmt is not None
|
||||
levelname_fmt_match = self.LEVELNAME_FMT_REGEX.search(self._fmt)
|
||||
if not levelname_fmt_match:
|
||||
return
|
||||
levelname_fmt = levelname_fmt_match.group()
|
||||
|
||||
for level, color_opts in self.LOGLEVEL_COLOROPTS.items():
|
||||
formatted_levelname = levelname_fmt % {
|
||||
"levelname": logging.getLevelName(level)
|
||||
}
|
||||
formatted_levelname = levelname_fmt % {"levelname": logging.getLevelName(level)}
|
||||
|
||||
# add ANSI escape sequences around the formatted levelname
|
||||
color_kwargs = {name: True for name in color_opts}
|
||||
colorized_formatted_levelname = terminalwriter.markup(
|
||||
formatted_levelname, **color_kwargs
|
||||
)
|
||||
self._level_to_fmt_mapping[level] = self.LEVELNAME_FMT_REGEX.sub(
|
||||
colorized_formatted_levelname, self._fmt
|
||||
)
|
||||
# add ANSI escape sequences around the formatted levelname
|
||||
color_kwargs = {name: True for name in color_opts}
|
||||
colorized_formatted_levelname = self._terminalwriter.markup(
|
||||
formatted_levelname, **color_kwargs
|
||||
)
|
||||
self._level_to_fmt_mapping[level] = self.LEVELNAME_FMT_REGEX.sub(
|
||||
colorized_formatted_levelname, self._fmt
|
||||
)
|
||||
|
||||
def format(self, record: logging.LogRecord) -> str:
|
||||
fmt = self._level_to_fmt_mapping.get(record.levelno, self._original_fmt)
|
||||
|
|
Loading…
Reference in New Issue