1

I use structlog in my project and I would like to (unit) test which handler has emitted which message. Is there a canonical way to do this? I noticed pytest-structlog but could not find any such functionality there. Or is there maybe something I could use from the stdlib / pytest?

So suppose my minimal example looks like

# implementation
import logging.handlers

import structlog

structlog.configure(
    wrapper_class=structlog.make_filtering_bound_logger(logging.NOTSET),
    context_class=dict,
    logger_factory=structlog.stdlib.LoggerFactory(),
    cache_logger_on_first_use=False,
)

h1 = logging.StreamHandler()
h1.setLevel(logging.ERROR)

h2 = logging.StreamHandler()
h2.setLevel(logging.DEBUG)

logging.root.addHandler(h1)
logging.root.addHandler(h2)


# test
import structlog

from dummy import minimal


def test_minimal(log):
    logger = structlog.getLogger()

    logger.warn("I am a warning.")
    logger.error("I am an error.")

    assert log.has("I am a warning.")
    assert log.has("I am an error.")

    # how to test what has been emitted by which handler?
    # assert not log.handler1.has("I am a warning.")
Haydnspass
  • 67
  • 6

1 Answers1

0

You can find documentation on structlog’s testing affordances in https://www.structlog.org/en/stable/testing.html

The capturing part can be done either using capture_logs (context manager) or using CapturingLogger (lower-level).

To get the he name of the emitting logger, make sure you add the add_logger_name processor.

hynek
  • 3,647
  • 1
  • 18
  • 26
  • Thanks for pointing this out! However is there something to unit-test what an individual handler has emitted? – Haydnspass Jul 11 '21 at 12:25
  • 1
    Could you be more specific what you mean by that? What do you miss from the `with capture_logs() as cap_logs:` example together with `add_logger_name`? I should preemptively point out that structlog has no concepts of handlers. So if you want to make assertions about stuff that happened _after_ structlog handed off the log message to `logging`, you have to use logging means. – hynek Jul 12 '21 at 13:04