OpenTelemetry Integration
Send your services' OpenTelemetry traces and logs to Ashr Labs over OTLP/HTTP, then view them — waterfalls, correlated logs, and LLM-powered analysis — in the OpenTelemetry panel of the dashboard.
Bring your own telemetry. Unlike SDK-based Observability (where our SDK produces the traces), this path ingests telemetry your own stack already emits via any OpenTelemetry Collector or SDK. No code changes to your app — just point an exporter at us. Requires the
otel_ingestfeature flag on your tenant (ask us to enable it).
What's supported
| Protocol | OTLP/HTTP (application/x-protobuf or application/json), gzip or uncompressed |
| Signals | Traces (spans) and Logs. Metrics are not ingested. |
| Not supported | OTLP/gRPC (:4317). Use the HTTP exporter. |
| Endpoint | https://api.ashr.io/testing-platform-api |
| Auth | Authorization: Bearer tp_<your-api-key> |
Your API key is the same tp_ key you use elsewhere with Ashr Labs — see Authentication. Every request is scoped to the tenant that owns the key; you can only ever read or write your own data.
Quick start — OpenTelemetry Collector
Add an otlphttp exporter and route your traces and logs pipelines to it:
exporters:
otlphttp/ashr:
endpoint: https://api.ashr.io/testing-platform-api # the API host — NOT lab.ashr.io, and NOT the :4317 gRPC port
headers:
Authorization: "Bearer tp_<your-api-key>"
compression: gzip # default; supported
# The exporter's built-in retry + queue handle transient 5xx for you.
retry_on_failure:
enabled: true
sending_queue:
enabled: true
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlphttp/ashr]
logs:
receivers: [otlp]
exporters: [otlphttp/ashr]
The exporter automatically appends /v1/traces and /v1/logs to endpoint. That's it — restart the Collector and data starts flowing.
Quick start — OpenTelemetry SDK (no Collector)
If you export straight from an instrumented app, point the standard OTLP/HTTP env vars at us:
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.ashr.io/testing-platform-api
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer tp_<your-api-key>"
Any OTLP/HTTP-capable SDK (Python, Node, Go, Java, …) works — these are standard OpenTelemetry variables, nothing Ashr-specific.
Verify it's working
Send one span with curl (OTLP/JSON):
curl -sS -X POST https://api.ashr.io/testing-platform-api/v1/traces \
-H "Authorization: Bearer tp_<your-api-key>" \
-H "Content-Type: application/json" \
-d '{"resourceSpans":[{"resource":{"attributes":[
{"key":"service.name","value":{"stringValue":"hello-otel"}}]},
"scopeSpans":[{"spans":[{
"traceId":"5b8aa5a2d2c872e8321cf37308d69df2","spanId":"b7ad6b7169203331",
"name":"smoke-test","kind":1,
"startTimeUnixNano":"'$(date +%s)'000000000","endTimeUnixNano":"'$(date +%s)'005000000",
"status":{"code":1}}]}]}]}'
A 200 with an empty body ({}) means it was accepted. Open the OpenTelemetry tab in the dashboard and it appears within seconds under the hello-otel service.
What you see in the dashboard
The OpenTelemetry tab (visible once the otel_ingest flag is on) shows:
- Overview — trace count, span count, error rate, p95/avg span duration, and spans-by-service, over a 24h / 7d / 30d window.
- Traces — a list of recent traces; click one for a time-proportional waterfall of its spans (nested by parent, error spans highlighted, click a span for its attributes) plus the logs correlated to that trace (by
traceId). - AI analysis (BYOK) — Analyze failures (root-causes error spans + logs) and Detect anomalies (flags latency outliers). These run on your own Anthropic key — store it once via the dashboard or
set_tenant_llm_key; it's encrypted at rest and used only for your analyses.
How your data maps
- Spans →
service.name(from resource attributes), span name, kind (SERVER/CLIENT/INTERNAL/…), start/end, duration, status (OK/ERROR + message), and all span + resource attributes (preserved as-is, including nested values). - Logs → timestamp, severity (number + text), body, and
traceId/spanIdfor correlation, plus attributes. traceId/spanIdare stored as lowercase hex. The authenticated tenant is always the owner — nothing in the payload can change that.
Limits & responses
| Limit | Value |
|---|---|
| Max request body | 5 MiB (compressed and after decompression) |
| Max records per request | 5,000 spans or logs |
| Rate limit | per-tenant; batch accordingly |
| Status | Meaning | What to do |
|---|---|---|
200 | Accepted | — |
401 | Missing/invalid key, or otel_ingest not enabled for your tenant | Check the Authorization header; ask us to enable the flag |
402 | Usage/billing limit reached | See billing |
413 | Payload or batch too large | Reduce batch size |
415 | Unsupported Content-Encoding | Use gzip or none |
429 | Rate limited | Back off / batch |
503 | Telemetry store waking up (transient) | Retry — the Collector does this automatically |
First batch after a quiet period. Our ClickHouse store scales to zero when idle and takes a few seconds to wake. The first request after idle may return
503; the Collector'sretry_on_failure(enabled above) resends it and it succeeds once the store is warm. Keep retries + the sending queue on and you'll never lose data to this.
Troubleshooting
- Everything 401s → the
Authorizationheader is missing/misspelled, the key is wrong, orotel_ingestisn't enabled for your tenant (ask us). - Connection refused / nothing arrives on gRPC → OTLP/gRPC (
:4317) is not supported. Use theotlphttpexporter and the HTTPS endpoint above. - 404 / requests hit the wrong host → the endpoint is
https://api.ashr.io/testing-platform-api(the API), nothttps://lab.ashr.io(the dashboard). - No traces in the UI but you're getting 200s → confirm you're looking at the right tenant/time window; traces appear under their
service.name.
See also
- Authentication — getting and using your
tp_API key - Observability — SDK-based production tracing (we produce the traces)