Skip to main content
OpenTracy ghost mascot peacefully watching the traffic — traces are quiet, always-on observation A trace is a row that records one LLM call: what was asked, what came back, which model answered, how much it cost, and how long it took. Traces are the single source of truth for everything downstream: auto-routing, evaluation, dataset curation, and distillation. If you don’t have traces, you don’t have a product.

What’s in a trace

Every completion that flows through the OpenTracy engine is persisted with this shape: Where they live: a ClickHouse column-store, designed so that billion-row aggregations (cost per model per day, latency p99 per alias) stay fast. How they’re created: you don’t call a separate log_trace() API. Any request that hits /v1/chat/completions on the engine — whether from the Python SDK, the OpenAI SDK pointed at the engine URL, or a raw curl — is traced automatically.

How traces are created (three paths)

Path A — Python SDK

Path B — OpenAI SDK (drop-in)

Path C — Raw HTTP

Any OpenAI-compatible client works, because the engine speaks that protocol.

Inspecting traces

The REST API exposes a search interface:
Returns a list of trace rows matching the filter. Filters supported include model, provider, routing_alias, status, tenant_id, since, until, and full-text search on input_text / output_text. In the UI, traces live under Traces → Browse with filters, a cost/latency chart on top, and a detail drawer that shows the full prompt + response and lets you “add to dataset”.

Attaching metadata

You control metadata — use it to link traces back to your app’s world:
When you go to build a dataset later, these fields are how you say “give me all traces from the ticket_classifier feature where the user gave positive feedback”.

Privacy and PII

Traces store full prompt and response text by default — that’s what makes distillation possible. Two knobs for environments that can’t do that:
  • Set OPENTRACY_TRACE_REDACT=true to strip matched patterns (emails, phone numbers, credit cards) before persist.
  • Set OPENTRACY_TRACE_CONTENT=false to store only metadata + token counts + cost, dropping the text entirely. You lose distillation ability but keep cost analytics.
Per-trace override is possible via the trace header:

From trace to dataset

One trace is a row. A dataset is a curated bundle of many rows, grouped by intent. The transformation is covered in Datasets — that’s where the pipeline starts producing training-ready artifacts.