cayu.observability.otel
Public Cayu API. Definitions are grouped by their public source module, and definitions from private implementation modules appear on their package’s page; adding a symbol does not move existing links. The import shown at each entry is a supported public namespace. Read the Python API overview and install the required extra.
OpenTelemetryEventSink
Section titled “OpenTelemetryEventSink”from cayu.observability import OpenTelemetryEventSinkConvert cayu runtime events into OpenTelemetry spans.
Produces a root span per session, a child span per model step and per tool
call, with token usage in the GenAI semantic conventions. Spans are managed
manually (started on *_STARTED events, ended on *_COMPLETED/*_FAILED)
because events arrive as discrete callbacks, not nested context-manager scopes.
Notes:
- Opt-in: register it via CayuApp(event_sinks=[...]). Nothing is traced
unless the sink is registered.
- Propagation: the session root span is parented from parent_session_id
(in-process subagents) or a W3C traceparent carried in the session
metadata (inbound HTTP). With no explicit parent the session starts a fresh
trace root rather than inheriting any ambient span. For cross-process
dispatched work, the caller injects traceparent_for into the child
DispatchRequest.metadata (cayu does not inject it automatically).
- Spans are closed by the matching terminal event. A session that ends without
one (e.g. a bare task cancellation that re-raises without emitting a terminal
session.* event) leaves its open spans unflushed; the sink relies on the
runtime emitting a terminal event per session. As a bounded safety net, once
more than _MAX_OPEN_SESSIONS are open a new session evicts the
least-recently-active one (by event timestamp), incrementing
evicted_sessions.
- Timing: span start_time/end_time come from Event.timestamp (when
the work happened), not from when the sink processes the event, so a buffered
event bus or a slow downstream sink does not skew latency traces.
Bases: EventSink.
emit (method)
Section titled “emit (method)”async OpenTelemetryEventSink.emit(event: Event) -> Noneemit_timing (method)
Section titled “emit_timing (method)”async OpenTelemetryEventSink.emit_timing(record: RuntimeTimingRecord) -> Noneinit (method)
Section titled “init (method)”OpenTelemetryEventSink.__init__(*, tracer_name: str=DEFAULT_TRACER_NAME, tracer: Any | None=None, redactor: SecretRedactor | None=None) -> Noneevicted_sessions (property)
Section titled “evicted_sessions (property)”OpenTelemetryEventSink.evicted_sessions() -> intNumber of sessions force-closed by the staleness safety net.
A non-zero value means the runtime failed to emit a terminal session.*
event for that many sessions (their spans were orphaned and swept). Surface
it in health checks: it points at a runtime-side event leak, not a bug here.
traceparent_for (method)
Section titled “traceparent_for (method)”OpenTelemetryEventSink.traceparent_for(session_id: str) -> str | NoneReturn the W3C traceparent for an active session’s root span.
Inject this into a child DispatchRequest.metadata['traceparent'] so
dispatched work continues the same trace. Returns None if the session
has no open span.