Skip to Content
Rius

How do I send traces from the OpenTelemetry Java SDK to Rius?

Rius accepts traces from the OpenTelemetry Java SDK over OTLP/HTTP, so you set the endpoint, protocol and Authorization header and send spans without the Rius SDK. Point the exporter at https://ingest.eu.console.rius-glassflow.com, use http/protobuf, and pass your API key as a Bearer token. Run one traced call and open it under Traces in the console to confirm it arrived.

How it works

Java has no native Rius SDK (those exist for Python and TypeScript), but the ingest endpoint is standard OTLP over HTTP, so any OpenTelemetry SDK can send to it. The Vanilla OpenTelemetry SDKs page covers this path for every language, and Trace LLM calls with OpenTelemetry compares it with the other ways in.

The pieces for Java:

  • Endpoint. The base URL is https://ingest.eu.console.rius-glassflow.com. The exporter variables append the path, so traces post to https://ingest.eu.console.rius-glassflow.com/v1/traces. The host carries your workspace’s region, and eu is the region documented.
  • Protocol. Use http/protobuf, which is recommended. http/json also works. There is no gRPC endpoint, so a gRPC exporter does not connect.
  • Authorization header. Send authorization=Bearer followed by your API key. The key starts with ri_ and decides which workspace the traces land in.
  • Where the variables apply. The standard OTEL_EXPORTER_OTLP_* variables take effect through the SDK, not on their own. In Java, build the SDK with AutoConfiguredOpenTelemetrySdk, which reads the protocol variable, and leave the exporter’s endpoint and headers unset in code. The zero-code Java agent reads them too.

Set it up

  1. Create an API key in the Rius console, which you reach at https://console.rius-glassflow.com. Use the key for the workspace you want the traces in.
  2. Set the exporter variables in the environment of your Java process:
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.eu.console.rius-glassflow.com" export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer <your API key>" # Rius ingests traces only, so turn off the metrics and logs exporters export OTEL_METRICS_EXPORTER=none export OTEL_LOGS_EXPORTER=none
  1. Set OTEL_SERVICE_NAME to the name you want your agent to appear under, for example my-agent. Also set OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT to 4096. The default limit of 128 attributes is too low once a span carries messages or tool definitions as one attribute per field.
  2. Create the SDK with AutoConfiguredOpenTelemetrySdk, or start the app with the zero-code Java agent. Do not set an endpoint or headers on the exporter in code, or they override the variables. For the SDK route, add the io.opentelemetry:opentelemetry-sdk-extension-autoconfigure and io.opentelemetry:opentelemetry-exporter-otlp dependencies. Autoconfiguration registers a shutdown hook that flushes queued spans when the JVM exits.
import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; // Reads the OTEL_* variables, so no endpoint or headers in code OpenTelemetrySdk sdk = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk(); Tracer tracer = sdk.getTracer("my-agent");
  1. Wrap each agent run in one root span and nest the model and tool spans under it. They arrive as one trace, and the root’s name, duration and status drive the run-level views.

  2. Put the model details on each model-call span. A span becomes a full generation, with cost computed by Rius, when it has these attributes:

    • openinference.span.kind set to LLM
    • gen_ai.operation.name
    • gen_ai.request.model
    • gen_ai.provider.name
    • gen_ai.usage.input_tokens and gen_ai.usage.output_tokens
    • gen_ai.response.model
    • gen_ai.output.messages

    Do not send a cost attribute. The Vanilla OpenTelemetry SDKs example shows these keys on one span.

If you use instrumentation that already emits gen_ai.* attributes, you do not set them yourself.

What you get

  • Traces from your Java service in the Rius trace list, with the span tree you built.
  • For each model-call span with the attributes above, the model name, token counts and a cost shown as a list-price estimate in US dollars.
  • Spans that arrive without a model or tokens are still stored. Their detail depends on which attributes your instrumentation emits.

After the first run, check these in order:

  1. Open Traces in the console and open the new trace. The model-call span should show a model name, token counts and cost.
  2. If nothing arrives, a 401 from the endpoint means the API key is wrong or revoked.
  3. If a span arrives without a model or tokens, check that no Collector attributes or transform processor strips gen_ai.* keys. Also check that the span stays under the attribute count limit you set.
  4. If you send through a Collector, give its otlphttp exporter the base URL. Use otlphttp, not otlp, which speaks gRPC.

The Interoperability section lists the sender guides and the attribute contract.

When something else fits

  • For a Python or TypeScript service, the Rius SDK sets up the exporter for you and adds message normalization, export-time privacy controls and auto-instrumentation of LLM libraries.
  • If several services or backends share one pipeline, send through an OpenTelemetry Collector with the otlphttp exporter and add Rius as one more entry.
  • Rius ingests traces only. Autoconfiguration also starts metrics and logs exporters aimed at the same endpoint, so turn them off with the two variables in step 2.

Still stuck? Get help

Last updated on