Skip to content

Getting started

This tutorial walks through emitting your first structured evidence, adding correlation, and capturing records in a test.

1. Install

pip install obslog

2. Emit an event

An event is a stable, dotted name plus structured fields — not a format string.

import obslog

log = obslog.get_logger(__name__)
log.info("order.completed", order_id=7, duration_ms=12)

With no configuration, obslog writes a human-readable line to stderr on a TTY and deterministic JSON when the output is piped.

3. Attach context

bind() returns a new logger with fixed fields; context() sets ambient correlation that flows across calls and async boundaries.

log = log.bind(component="checkout")

with obslog.context(execution_id=obslog.new_id(), request_id="req-42"):
    log.info("order.received", order_id=7)  # inherits execution_id + request_id

4. Scope an operation

operation() records duration, links a child execution to its parent, and captures exceptions as structured evidence.

with log.operation("charge_card", phase="authorize") as op:
    op.set(amount=100)
    charge()  # on error: an ERROR record with the exception + duration is emitted

5. Report failures as evidence

try:
    charge()
except TimeoutError as exc:
    log.error("gateway.failed", error=exc, error_code="DB_TIMEOUT", order_id=7)

error_code is a stable identifier an AI agent can cluster on; the exception is captured as a structured error object.

6. Test it

from obslog.testing import capture


def test_emits_completion():
    with capture() as records:
        obslog.get_logger("t").info("order.completed", order_id=7)
    assert records[0].event == "order.completed"
    assert records[0].metadata == {"order_id": 7}

Next steps