Data Model

Tael normalizes incoming OTLP into four kinds of records: spans, logs, metrics, and trace comments. Every record carries a trace_id where one exists, which is what makes cross-signal correlation a single query rather than a manual join.

Spans

A span is one unit of work — a request handler, a job, an LLM call, a tool invocation. This is the primary record you query in Tael.

  • Name
    trace_id
    Type
    string
    Description

    Groups all spans, logs, and metrics for one logical operation.

  • Name
    span_id / parent_span_id
    Type
    string
    Description

    Position within the trace tree. The root span has no parent.

  • Name
    service
    Type
    string
    Description

    From OTEL_SERVICE_NAME / service.name.

  • Name
    operation
    Type
    string
    Description

    The span name (e.g. http.request, host.prompt).

  • Name
    start_time / end_time / duration_ms
    Type
    timestamp / ms
    Description

    Wall-clock timing. Use span duration for timing, not a separate metric.

  • Name
    status
    Type
    ok | error | unset
    Description

    Set error on failure and Tael surfaces it in --status error queries.

  • Name
    kind
    Type
    enum
    Description

    INTERNAL (default), CLIENT, SERVER, LLM, or TOOL.

  • Name
    attributes
    Type
    JSON map
    Description

    Arbitrary key/value facts. This is where wide events live.

  • Name
    events
    Type
    array
    Description

    Timestamped events within the span, including recorded exceptions.

LLM spans

When a span's kind is LLM, Tael extracts the OpenTelemetry gen_ai.* semantic conventions into typed, queryable columns instead of leaving them buried in the attributes map:

  • Name
    provider / model
    Type
    string
    Description

    e.g. anthropic / claude-opus-4-7. From gen_ai.request.model.

  • Name
    operation
    Type
    chat | completion | embedding | tool
    Description

    The kind of model call.

  • Name
    input_tokens / output_tokens / total_tokens
    Type
    int
    Description

    From gen_ai.usage.input_tokens / gen_ai.usage.output_tokens.

  • Name
    cost_usd
    Type
    float
    Description

    Cost of the call, when reported.

  • Name
    ttft_ms / inter_token_ms
    Type
    ms
    Description

    Time to first token and mean inter-token latency.

  • Name
    prompt_sha256 / completion_sha256
    Type
    string
    Description

    Hashes of the prompt and completion blobs, so payloads are deduplicated and full-text searchable.

  • Name
    finish_reason / temperature
    Type
    string / float
    Description

    stop, length, content_filter, etc., and the sampling temperature.

Because these are real columns, you can ask things like "slow prompt calls last hour" or "total cost by model today" directly with tael query traces or tael query sql.

Logs

  • Name
    timestamp / observed_timestamp
    Type
    timestamp
    Description
  • Name
    severity
    Type
    trace | debug | info | warn | error | fatal
    Description
  • Name
    body
    Type
    string
    Description

    The log message. Oversized bodies are stored as blobs.

  • Name
    service
    Type
    string
    Description
  • Name
    trace_id / span_id
    Type
    string
    Description

    Set when the log was emitted inside an active span — this is what links logs to traces.

  • Name
    attributes
    Type
    JSON map
    Description

Metrics

  • Name
    metric_name
    Type
    string
    Description
  • Name
    metric_type
    Type
    gauge | counter | histogram | summary | unknown
    Description

    Prometheus remote-write v1 loses type information, so those points land as unknown.

  • Name
    value
    Type
    float
    Description
  • Name
    timestamp
    Type
    timestamp
    Description
  • Name
    labels
    Type
    map
    Description
  • Name
    service
    Type
    string
    Description

Trace comments

Annotations attached to a trace (optionally to a specific span) that persist across sessions. See Trace Comments for the full model and the structured conventions agents use.

Querying it all

These four record types are exposed as SQL tables — spans, logs, metrics, and trace_comments — through tael query sql:

tael query sql "SELECT service, COUNT(*) AS n FROM spans WHERE status = 'error' GROUP BY service ORDER BY n DESC"

Was this page helpful?