- Observers — log per-call signals (user→bot latency, turn timing, LLM, transcription, startup). No external infrastructure; they just log.
- OpenTelemetry tracing — emits a span tree per call (conversation → turn → STT/LLM/TTS) with TTFB and token counts, exported to any OTLP backend (Jaeger, Grafana Tempo, Datadog, Honeycomb, …).
Tracing
Each call becomes one trace whoseconversation_id is the call_id, so a trace joins straight back to the call record. The span tree:
turncall.project_id, turncall.agent_id, turncall.direction, and turncall.transport — plus turncall.from_number / turncall.to_number unless you turn PII off (below).
Enable it
Point TurnCall at an OTLP collector:Production requires an endpoint. Tracing never falls back to console output in production — synchronous stdout writes would stall the realtime audio path. With no
OTEL_EXPORTER_OTLP_ENDPOINT set in production, tracing self-disables with a warning. In development, tracing prints spans to the console when no endpoint is configured.Observers
The five observers log to the application logger on every call:
They supplement the server events / webhook transcript stream (which is your product data) — observers are operational logging for debugging “why did that call feel slow?”.