Skip to content

Commit

Permalink
Feature: add an option for a custom formatter in logging setup (#10)
Browse files Browse the repository at this point in the history
* feat(logging): setup support user-given formatters

Allow the user to provide a custom formatter class to replace the
default `logging.Formatter`. This should allow more flexibility to
customize the logs output.
The `format` argument is kept for backward compatibility.

* test(logging): ensure setup's formatter is handled

Test that the user can set a custom formatter in `clapper.logging.setup`
  • Loading branch information
Yannick-Dayer authored Sep 26, 2024
1 parent d17d303 commit 92c483e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
19 changes: 13 additions & 6 deletions src/clapper/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def setup(
format: str = "[%(levelname)s] %(message)s (%(name)s, %(asctime)s)", # noqa: A002
low_level_stream: typing.TextIO = sys.stdout,
high_level_stream: typing.TextIO = sys.stderr,
formatter: logging.Formatter | None = None,
) -> logging.Logger:
"""Return a logger object that is ready for console logging.
Expand All @@ -40,10 +41,13 @@ def setup(
and above to the text-I/O stream ``high_level_stream``, with an internal
level set to ``logging.WARNING``.
A new formatter, with the format string as defined by the ``format``
argument is set on both handlers. In this way, the global logger level can
still be controlled from one single place. If output is generated, then it
is sent to the right stream.
If you do not provide a ``formatter`` argument, a new formatter, with the
format string as defined by the ``format`` argument is set on both handlers.
In this way, the global logger level can still be controlled from one single
place. If output is generated, then it is sent to the right stream.
You can provide a custom formatter if ``format`` is not sufficient to
customize the looks of your logs (e.g. you want to add colors).
Parameters
----------
Expand All @@ -52,11 +56,13 @@ def setup(
format
The format of the logs, see :py:class:`logging.LogRecord` for more
details. By default, the log contains the logger name, the log time,
the log level and the massage.
the log level and the message. *Ignored if ``formatter`` is set*.
low_level_stream
The stream where to output info messages and below
high_level_stream
The stream where to output warning messages and above
formatter
A formatter to replace the default :py:class:`logging.Formatter`.
Returns
-------
Expand All @@ -66,7 +72,8 @@ def setup(

logger = logging.getLogger(logger_name)

formatter = logging.Formatter(format)
if formatter is None:
formatter = logging.Formatter(format)

handlers_installed = {k.name: k for k in logger.handlers}
debug_logger_name = f"debug_info+{logger_name}"
Expand Down
26 changes: 26 additions & 0 deletions tests/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ def test_logger_setup():
assert hi.getvalue() == "warning message\nerror message\n"


def test_logger_setup_formatter():
log_output = io.StringIO()

custom_formatter = logging.Formatter(fmt="custom {message:s}", style="{")

logger = clapper.logging.setup(
"awesome.logger",
low_level_stream=log_output,
high_level_stream=log_output,
formatter=custom_formatter,
)
logger.setLevel(logging.DEBUG)

logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")

assert log_output.getvalue() == (
"custom debug message\n"
"custom info message\n"
"custom warning message\n"
"custom error message\n"
)


def test_logger_click_no_v():
lo = io.StringIO()
hi = io.StringIO()
Expand Down

0 comments on commit 92c483e

Please sign in to comment.