Skip to Content

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, @agent and @tool decorators, and their TypeScript forms such as withAgent.
  • OpenLLMetry’s auto-instrumentation of your model clients.
  • Conversation ids set with @conversation, set_conversation_id or withConversation.

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.input and traceloop.entity.output are shown as the span’s input and output.
  • gen_ai.conversation.id, which OpenLLMetry writes for conversations, is read as the session.
  • app_name or appName becomes service.name, which names the agent your traces are grouped under.
  • Association properties such as user_id and chat_id arrive as traceloop.association.properties.* attributes. You can inspect and filter on them, but Rius does not treat them as users or sessions.

Set it up

  1. Create a Rius workspace and an API key. Keys start with ri_.

  2. Point OpenLLMetry at Rius by changing its environment variables. Ingest is at https://ingest.eu.console.rius-glassflow.com, and OpenLLMetry appends /v1/traces itself:

    # 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
  3. Remove TRACELOOP_API_KEY and any old values from your deployment. In Python, TRACELOOP_BASE_URL and TRACELOOP_HEADERS override the arguments you pass to Traceloop.init(), so leftovers win. In TypeScript the init arguments win.

  4. Keep the base URL an http or https address. Rius accepts OTLP over HTTP only, not gRPC. In Python, leave TRACELOOP_METRICS_ENABLED set to false: the SDK would otherwise send OTLP metrics, which Rius does not ingest, and each export logs a 404. Traces are unaffected either way.

  5. If you want Rius to group traces by end user, set user.id yourself, 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)
  6. 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.

Still stuck? Get help

Last updated on