Can I send traces from an OpenTelemetry Collector to Rius unchanged?
Yes, Rius accepts spans from an OpenTelemetry Collector as they are: add an otlphttp exporter that points at the Rius ingest endpoint and carries your API key in an authorization header. Rius reads the GenAI attributes (gen_ai.*) already on your spans and computes cost itself. You change the Collector config, not your applications.
How it works
The Collector forwards spans unchanged, so Rius reads exactly what your applications emit, as if they exported directly. Rius reads:
- Model and tokens. Rius reads
gen_ai.request.model,gen_ai.usage.input_tokensandgen_ai.usage.output_tokensfrom each span, and the messages ingen_ai.input.messagesandgen_ai.output.messages. - Cost. Rius computes cost from the model and token counts. You never send a cost or latency value, and the Collector should not add one.
- Other conventions. Spans from OpenInference, OpenLLMetry and Traceloop, Laminar, the Vercel AI SDK 5 and 6, and Pydantic AI are normalized at ingest, so they get the same model, token and cost analytics.
The ingest endpoint is OTLP over HTTP, with http/protobuf recommended or http/json. It accepts gzip and a body of up to 16 MiB. There is no gRPC endpoint, so use the otlphttp exporter, not otlp. Rius ingests traces only, so keep metrics and logs pipelines pointed at other backends.
The otlphttp exporter appends /v1/traces to the base URL itself. The key goes in an Authorization Bearer header, and the key decides which workspace the traces land in. The sender guides are collected on the Interoperability page.
Set it up
-
Create an API key in the console . Export it as
RIUS_API_KEYin the environment where the Collector runs, so the key stays out of the config file. -
Add the exporter and put it in your traces pipeline. The host carries your workspace’s region in the subdomain, and the example uses
eu.
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch: {}
exporters:
otlphttp/glassflow:
endpoint: https://ingest.eu.console.rius-glassflow.com
# proto is the default encoding and the recommended one; json works too
encoding: proto
compression: gzip
headers:
authorization: Bearer ${env:RIUS_API_KEY}
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/glassflow]- To try Rius next to a backend you already use, add it as one more entry in
exporters. No application changes are needed.
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/glassflow, otlphttp/existing]otlphttp/existing stands for the exporter your config already defines for the other backend.
-
Restart the Collector, run one traced LLM call, and open Traces in the console. The span for the model call should show a model name, token counts and cost.
-
If analytics fields are empty, check your Collector processors. An
attributesortransformprocessor that renames or dropsgen_ai.*keys removes what Rius reads. Also check that the span has not hit OpenTelemetry’s default limit of 128 attributes, which long LLM spans can exceed. Raise it in the application, for example withOTEL_SPAN_ATTRIBUTE_COUNT_LIMITset to 4096. A401from the endpoint means the API key is wrong or revoked.
The Collector page covers the exporter in full.
What you get
- Traces from your existing pipeline in Rius, with the model, token usage and messages on the span for each model call.
- Cost per call, computed by Rius as a list-price estimate in US dollars.
- Fan-out: the same spans can go to Rius and to another backend at once.
- A single egress point and local buffering, if those are why you run a Collector.
Set these in your applications. The Collector can add a fixed service.name or service.version with a resource processor, but not per-request values such as session.id and user.id:
session.idanduser.idon every span, root included. Withoutsession.ida trace is its own session, and withoutuser.idit counts as anonymous. Prefer an opaque user id to an email.service.nameandservice.version, so agents and versions are grouped and compared.- A model name and token counts on each model call. Without them the span has no cost.
When something else fits
- If your applications are in Python or TypeScript and have no OpenTelemetry setup yet, the Rius SDK is one
init()call. Trace LLM calls with OpenTelemetry compares every path on one page. - If you have no Collector, point an OpenTelemetry SDK, OpenLLMetry or OpenInference exporter straight at the Rius endpoint.