Can I keep my OpenTelemetry instrumentation when I leave Traceloop?
Yes, Rius reads OpenLLMetry, Traceloop’s SDK, as plain OpenTelemetry, so you keep your decorators and auto-instrumentation and change only where they export. You set a new base URL and an auth header, and your agents, tools and LLM calls show up in Rius as such. The full walkthrough is in Migrate from Traceloop to Rius.
How it works
OpenLLMetry exports standard OTLP over HTTP to whichever endpoint you give it. Rius takes OTLP over HTTP with a Bearer API key, so nothing in your code has to change. Rius is built around OpenTelemetry conventions, and the interoperability overview lists every sender path that works without the Rius SDK.
What stays in place:
- Your
@workflow,@task,@agentand@tooldecorators, and their TypeScript forms such aswithAgent. - OpenLLMetry’s auto-instrumentation of your model clients.
- Conversation ids set with
@conversation,set_conversation_idorwithConversation.
What Rius reads from those spans:
- LLM calls become generations with the request and response model, input and output tokens, and cache-read tokens. Cost is computed by Rius from the model and token counts, so you never send it.
- Agent and tool decorators appear as agent and tool spans, named after the decorated function. Workflows and tasks appear as generic steps.
traceloop.entity.inputandtraceloop.entity.outputare shown as the span’s input and output.gen_ai.conversation.id, which OpenLLMetry writes for conversations, is read as the session.app_nameorappNamebecomesservice.name, which names the agent your traces are grouped under.- Association properties such as
user_idandchat_idarrive astraceloop.association.properties.*attributes. You can inspect and filter on them, but Rius does not treat them as users or sessions.
Set it up
-
Create a Rius workspace and an API key. Keys start with
ri_. -
Point OpenLLMetry at Rius by changing its environment variables. Ingest is at
https://ingest.eu.console.rius-glassflow.com, and OpenLLMetry appends/v1/tracesitself:# Before: Traceloop export TRACELOOP_API_KEY="<your Traceloop API key>" # After: Rius export TRACELOOP_BASE_URL="https://ingest.eu.console.rius-glassflow.com" export TRACELOOP_HEADERS="Authorization=Bearer%20<your Rius API key>" export TRACELOOP_METRICS_ENABLED="false" # Python SDK only -
Remove
TRACELOOP_API_KEYand any old values from your deployment. In Python,TRACELOOP_BASE_URLandTRACELOOP_HEADERSoverride the arguments you pass toTraceloop.init(), so leftovers win. In TypeScript the init arguments win. -
Keep the base URL an
httporhttpsaddress. Rius accepts OTLP over HTTP only, not gRPC. In Python, leaveTRACELOOP_METRICS_ENABLEDset tofalse: the SDK would otherwise send OTLP metrics, which Rius does not ingest, and each export logs a 404. Traces are unaffected either way. -
If you want Rius to group traces by end user, set
user.idyourself, because OpenLLMetry does not. Rius lists a trace under the user of its root span, so set it inside your outermost decorated function:from opentelemetry import trace trace.get_current_span().set_attribute("user.id", user_id) -
Send one request and check that the trace tree shows your workflow, agent and tool spans, that the generation shows model and tokens, and that cost appears. Set the conversation id before the root span starts, so the trace lands in the right session.
To compare before you cut over, route OpenLLMetry through an OpenTelemetry Collector and export to both backends. The migration overview explains the options, and the Traceloop guide has the Collector configuration.
What you get
- No re-instrumentation. Your existing spans arrive with their structure intact.
- Models, tokens and cost per call, computed by Rius as list-price estimates in US dollars.
- Sessions from your conversation ids, and users once you set
user.id. - Alerts, and an MCP server so your coding agent can query production traces.
- A reversible move: you can send the same traces to Traceloop and Rius while you evaluate.
If you want Rius-native session and user scopes, privacy controls or partial spans, you can later swap OpenLLMetry for the Rius SDK. That is optional. Remove OpenLLMetry first, because running both in one process produces duplicate LLM spans.
When something else fits
- If your code calls Traceloop platform features such as
get_prompt(), guardrails, user feedback, datasets or experiments, keep OpenLLMetry pointed at Traceloop and add Rius through a Collector fan-out. In Python, re-pointing the base URL switches those features off. - Rius has no evals, prompt registry, datasets, experiments or gateway, so keep those workflows in the tool that provides them.
- Existing traces stay in Traceloop. Rius starts from the first span you send it.