How do I get LLM cost with OpenInference instrumentors?
Rius computes LLM cost for OpenInference instrumentors on its own, from the model name and token counts they already record, so you send no cost attribute. Point an OTLP exporter at the Rius ingest endpoint and raise OpenTelemetry’s span attribute limit to 4096. OpenInference does not raise that limit for you, and without it a long agent run can lose the model and token counts that cost needs.
How it works
Rius prices a call from gen_ai.request.model plus the gen_ai.usage.* token counts: input, output, cache read and cache write, each at its own rate. OpenInference instrumentors do not write those keys. They write their own, and Rius maps them at ingest:
- The request model comes from
llm.request.model_name, else themodelmember ofllm.invocation_parameters, elsellm.model_name. It lands ongen_ai.request.model. llm.token_count.promptandllm.token_count.completion, with their cache and reasoning details, fill thegen_ai.usage.*counts.- Keys you already send under
gen_ai.*always win. The mapping fills gaps and never overwrites.
So the attributes cost needs are set for you by the instrumentor, and Rius renames them. The one thing that can break this is span size. OpenInference writes one attribute per message field and per tool field, and OpenTelemetry keeps only 128 attributes per span by default, dropping the rest without an error. An agent loop with about ten tools can pass that after six to nine turns. The span then loses attributes such as the model, tool definitions, usage and output, and a span with no model or no token counts gets no cost.
A span also gets no cost when its model is not in the price catalog. Costs are list-price estimates in US dollars from LiteLLM’s public model-price catalog, and an unknown model shows an empty cost, not zero.
Set it up
- Create an API key in the Rius console. The key decides which workspace the traces land in.
- Build a tracer provider with the attribute limit raised, add an OTLP exporter for the ingest endpoint, and pass the provider to the instrumentor. This exporter takes the full
/v1/tracespath:
from opentelemetry.sdk.trace import SpanLimits, TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from openinference.instrumentation.openai import OpenAIInstrumentor
provider = TracerProvider(span_limits=SpanLimits(max_span_attributes=4096))
provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(
endpoint="https://ingest.eu.console.rius-glassflow.com/v1/traces",
headers={"Authorization": "Bearer <your API key>"},
)
)
)
OpenAIInstrumentor().instrument(tracer_provider=provider)- In any other language, or when you cannot edit the provider code, raise the limit through the environment instead:
export OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT=4096- Run one traced LLM call, open Traces in the console, and open the new trace. The span for the model call shows the model name, token counts and cost.
- If the cost is empty, open the span and check two things: that a model name and at least one token count are present, and that the model is one the price catalog knows. Do not add a cost attribute. Rius ignores a cost attribute and computes cost from the model and tokens.
The Rius Python and TypeScript SDKs ship these same instrumentors and set the 4096 limit for you, so if your app is in either language you can skip steps 2 and 3. The general ways to send traces, including the Collector, are in Trace LLM calls with OpenTelemetry.
What you get
- A cost on each model-call span, estimated in US dollars from the model and token counts, with cache reads and writes priced at their own rates.
- Cost totals and a per-model breakdown across your traces, with no pricing code in your app.
- Searchable values under the
gen_ai.*keys. Filter ongen_ai.usage.input_tokens, not onllm.token_count.prompt, because the OpenInference source keys are removed once mapped. - Spans that keep their model, tools and usage on long agent runs, because the attribute limit no longer drops them.
The OpenInference page covers what else is captured, and the span attribute reference lists every attribute Rius reads and the full mapping.
When something else fits
- If you need prices that differ from list prices, such as negotiated, batch or priority discounts, Rius does not apply them, so treat its cost as an estimate and reconcile against your provider invoice.
- If you are on Python or TypeScript and want less wiring, the Rius SDK applies the same OpenInference mapping and the raised limit for you.