Skip to content

Observability recipes (low-cardinality tags)

See also: HTTP recipes, DB recipes, Worker recipes.

Redress emits lifecycle events via on_metric and on_log. These hooks are designed for metrics/logging without coupling to a specific backend.

Do (low-cardinality): - class (ErrorClass) - operation (stable operation name) - stop_reason - cause (exception or result) - event (retry, success, deadline_exceeded, etc.)

Don't (high-cardinality): - full URLs or query strings - user IDs, request IDs, trace IDs - raw SQL or exception messages - stack traces

If you need detailed diagnostics, log them separately at debug level, not as tags.

Copy/paste example

from redress import Policy, Retry, default_classifier
from redress.strategies import decorrelated_jitter


def metric_hook(event: str, attempt: int, sleep_s: float, tags: dict[str, object]) -> None:
    # Keep tags low-cardinality.
    print(f"event={event} attempt={attempt} sleep_s={sleep_s:.3f} tags={tags}")

policy = Policy(
    retry=Retry(
        classifier=default_classifier,
        strategy=decorrelated_jitter(max_s=3.0),
    )
)

policy.call(do_work, on_metric=metric_hook, operation="worker_task")

Stop reasons in execute()

If you need a structured stop reason, use execute() and inspect the outcome:

outcome = policy.execute(do_work, operation="worker_task")
print(outcome.stop_reason)

stop_reason is intentionally low-cardinality (ABORTED, DEADLINE_EXCEEDED, SCHEDULED, MAX_ATTEMPTS_EXCEEDED, etc.).