Observability¶
Automatic OTEL tracing for every message, LLM call, tool invocation, and supervisor restart. No instrumentation required.
See Observability for setup guides and the full span attribute reference.
Tracer¶
civitas.observability.tracer.Tracer(span_queue=None)
¶
Creates and enriches spans for Civitas operations.
Behaviour depends on the environment: - opentelemetry-sdk installed + OTEL_EXPORTER_OTLP_ENDPOINT set -> OTLP exporter - opentelemetry-sdk installed, no endpoint -> OTEL ConsoleSpanExporter - opentelemetry-sdk not installed -> built-in print-based console output
When span_queue is provided, completed spans are additionally pushed to the queue for consumption by OTELAgent (async, non-blocking export path).
Source code in civitas/observability/tracer.py
start_span(name, trace_id='', parent_span_id=None, attributes=None)
¶
Create a general-purpose span (for agent lifecycle, LLM calls, etc).
Source code in civitas/observability/tracer.py
start_send_span(message)
¶
Create a span for an outbound message send.
Source code in civitas/observability/tracer.py
start_receive_span(message)
¶
Create a span for an inbound message receive.
Source code in civitas/observability/tracer.py
start_llm_span(model, trace_id, parent_span_id=None)
¶
Create a span for an LLM call. Call end_llm_span() after the call completes.
Source code in civitas/observability/tracer.py
end_llm_span(span, *, tokens_in=0, tokens_out=0, cost_usd=0.0)
¶
Enrich and close an LLM span with response metrics.
Source code in civitas/observability/tracer.py
start_tool_span(tool_name, trace_id='', parent_span_id=None)
¶
Create a span for a tool invocation.
Source code in civitas/observability/tracer.py
end_tool_span(span, *, status='ok')
¶
Enrich and close a tool span with result status.
Source code in civitas/observability/tracer.py
new_trace_id()
¶
flush()
¶
Force-export any pending spans via this tracer's provider.
SpanQueue¶
civitas.observability.span_queue.SpanQueue(maxsize=10000)
¶
Thin asyncio.Queue wrapper for completed SpanData.
The Tracer puts spans here via put_nowait() (never blocks). OTELAgent drains this queue and calls the ExportBackend.
Source code in civitas/observability/span_queue.py
put_nowait(span)
¶
Enqueue a completed span. Drops oldest if full (never blocks).
Source code in civitas/observability/span_queue.py
civitas.observability.span_queue.SpanData(name, trace_id, span_id, parent_span_id, start_time, end_time, attributes=dict(), status='ok', error_message=None)
dataclass
¶
Completed span ready for export. All fields are plain Python types.
Export Backends¶
civitas.observability.export_backend.ExportBackend
¶
civitas.observability.export_backend.ConsoleBackend
¶
Prints a human-readable summary of each span to stdout via logging.