Observability¶
Roost ships with structured logging built in, plus optional OpenTelemetry and Prometheus integrations behind extras.
Logging¶
from roost.observability import configure_logging
configure_logging(level="INFO") # JSON in non-TTY, console in TTY
configure_logging is idempotent. The CLI’s roost run calls auto_configure_from_env() for you, so ROOST_LOG_LEVEL=DEBUG and ROOST_LOG_JSON=1 work out of the box.
Example log line (JSON):
{"event": "job.completed", "id": 42, "task": "send_email", "duration": 0.0123, "level": "info", "timestamp": "2026-05-07T20:32:11.842Z"}
Tracing — OpenTelemetry¶
pip install pgroost[otel]
Once opentelemetry-api is importable, enqueue injects the active trace context into each job’s args (under a private __roost_trace key the handler never sees), and the worker re-attaches it before invoking the handler. A span named job:<task> wraps every handler call with attributes for queue, task, attempt, and id.
If you’ve already configured an OTel SDK + exporter in your app, traces appear automatically.
Metrics — Prometheus¶
pip install pgroost[metrics]
Counters and a histogram are exposed under the standard prometheus_client registry:
Metric |
Type |
Labels |
|---|---|---|
|
Counter |
|
|
Counter |
|
|
Counter |
|
|
Histogram |
|
outcome is one of retryable, discarded, or cancelled. Wire prometheus_client.start_http_server(8000) in your app to expose them.
Without the extras¶
When neither package is installed, the hooks are no-ops — no runtime cost, no import errors.