CClawMetryDocs

Runtimes

OpenTelemetry ingest#

ClawMetry speaks OTLP in both directions. Anything that can emit OpenTelemetry can push into it, and ClawMetry can push its own telemetry out to the stack you already run.

This is the supported path for runtimes with no local store — n8n backed by Postgres, a hosted CI agent, a framework with native OTel support, or your own service.

Receiving#

Three HTTP endpoints on the dashboard:

EndpointPayload
POST /v1/tracesSpans — the agent's structure, tool calls, latencies
POST /v1/metricsCounters and gauges — tokens, cost, run counts
POST /v1/logsLog records — including cost-bearing events from runtimes that report cost as a log

Point any OTLP/HTTP exporter at http://localhost:8900:

bash
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8900
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf

Install the optional protobuf dependency to accept binary OTLP:

bash
pip install 'clawmetry[otel]'

Authentication#

OTLP ingestion accepts untrusted data that lands in your store, so it is authenticated like any other write surface. For a local-only setup where the receiver is not reachable off-box:

bash
CLAWMETRY_OTLP_ALLOW_UNAUTH=1 clawmetry

Do not set that on anything with a routable address.

Limits#

VariableDefaultPurpose
CLAWMETRY_OTLP_MAX_DECOMPRESSED_MB64Reject payloads that expand beyond this. Guards against decompression bombs.
CLAWMETRY_OTLP_APP_CAPCap on distinct applications accepted, so one misconfigured exporter cannot fill the store.
CLAWMETRY_MAX_REQUEST_MBGlobal request size cap.

Claude Code's native OTel#

Claude Code emits OpenTelemetry natively, and ClawMetry consumes it alongside the JSONL transcripts. Two things are worth knowing if you wire it up:

  • Cost arrives on both a log record and a metric. ClawMetry counts it once.

If you build your own pipeline on the same feed, do not sum both.

  • Session ids appear bare on the wire, not namespaced with a runtime

prefix, so anything joining OTel spans to sessions has to know that.

Spans map onto ClawMetry's model directly: an assistant turn becomes an llm.call, each tool_use a tool.<name> child, a Task an agent.spawn, and a thinking block an internal thinking span. That mapping is what the Agent Graph and turn-anatomy views are built on.

Querying what arrived#

bash
# traces, one row per trace_id with aggregate span stats
curl -s 'http://localhost:8900/api/local/traces?limit=20' | jq '.rows'

# spans, filtered
curl -s 'http://localhost:8900/api/local/spans?session_id=<sid>&limit=200' | jq '.rows'

# a single span
curl -s 'http://localhost:8900/api/local/spans/<span_id>' | jq

The Tracing tab renders the same data as a waterfall.

Exporting out#

ClawMetry can push its own metrics to your collector, so agent cost and activity land next to the rest of your infrastructure telemetry.

VariablePurpose
CLAWMETRY_OTEL_EXPORT_ENDPOINTOTLP endpoint to push to. Setting it starts the exporter.
CLAWMETRY_OTEL_EXPORT_HEADERSJSON object of headers, for auth against your collector
CLAWMETRY_OTEL_EXPORT_INTERVALExport cadence in seconds
bash
export CLAWMETRY_OTEL_EXPORT_ENDPOINT=https://otlp.example.com/v1/metrics
export CLAWMETRY_OTEL_EXPORT_HEADERS='{"x-api-key":"…"}'
export CLAWMETRY_OTEL_EXPORT_INTERVAL=60

Status and a manual trigger:

bash
curl -s localhost:8900/api/otel-status | jq
curl -s localhost:8900/api/otel/export | jq

Tier: the export path is otel_export, a Pro feature. Ingestion is not gated.

Which path should you use?#

You haveUse
A framework with OTel supportThis page — point the exporter at ClawMetry
Python code you can editThe interceptor — two lines, gets cost
Structured runs to pushThe ingest API — explicit run and event shape
A runtime that writes to diskAsk for an adapter — it is the highest-fidelity path
Cookie preferences