Logging

bozo provides structured logging. Each log event is a message plus a set of key-value fields. This makes logs easy to search, filter, and analyze.

Structured logging in practice

log.info("user_login", user_id=42, email="user@example.com")

The first argument is the event name. Additional fields are structured data.

Log levels

The logger supports the standard levels:

  • log.debug()
  • log.info()
  • log.warning()
  • log.error()
  • log.critical()

JSON-safe value constraints

bozo enforces JSON-safe log values. A log value must be one of:

  • str, int, float, bool, or None
  • list of JSON-safe values
  • dict[str, JSON-safe value]

Valid examples

log.info("ok", count=3, active=True)
log.info("list", values=[1, 2, 3])
log.info("nested", payload={"user": {"id": 1, "name": "Ana"}})

Invalid examples

log.info("bad", obj=object())
log.info("bad", when=datetime.utcnow())
log.info("bad", data=set([1, 2, 3]))

Convert non-JSON types to strings or primitives before logging.

Why structured logs

Structured logs are preferred because they are:

  • Searchable: fields can be indexed and queried.
  • Stable: schemas evolve without breaking parsers.
  • Machine-friendly: JSON output is ready for ingestion by log systems.

This site uses Just the Docs, a documentation theme for Jekyll.