Skip to main content
TurnCall instruments every call with two complementary mechanisms, both on by default:
  • 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, …).
Both cover cascade and S2S calls. See ADR-0010.

Tracing

Each call becomes one trace whose conversation_id is the call_id, so a trace joins straight back to the call record. The span tree:
Span attributes also carry 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:
Then make a call and the spans appear in your backend.
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?”.

Configuration

Local quick start

Run a collector with a traces UI, then point TurnCall at it: