Skip to main content

Documentation Index

Fetch the complete documentation index at: https://arize-ax.mintlify.dev/docs/llms.txt

Use this file to discover all available pages before exploring further.

The previous four pages — Resource, Exporter, Span Processor, and Tracer Provider — walked through the OpenTelemetry tracing components one by one. Wiring them up by hand in every application is verbose. The arize.otel SDK collapses all of it into a single function call — and adds a few OpenInference-specific capabilities on top. For the practical how-to of installing and using these helpers, see Set up tracing. This page covers what they do under the hood.

Appreciate the Simplicity

Configuring tracing with raw OpenTelemetry — Resource, Exporter, Span Processor, Tracer Provider — looks like this:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.resources import Resource
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter

def init_arize_tracing():
    resource = Resource.create({
        "openinference.project.name": ARIZE_PROJECT_NAME,
    })
    otlp_exporter = OTLPSpanExporter(
        endpoint="https://otlp.arize.com/v1",
        headers={
            "space_id": ARIZE_SPACE_ID,
            "api_key": ARIZE_API_KEY,
        },
    )
    span_processor = BatchSpanProcessor(otlp_exporter)

    tracer_provider = TracerProvider(resource=resource)
    tracer_provider.add_span_processor(span_processor)
    trace.set_tracer_provider(tracer_provider)

    return tracer_provider.get_tracer(ARIZE_PROJECT_NAME)
The Arize AX register() helper replaces all of that:
from arize.otel import register

tracer_provider = register(
    space_id=ARIZE_SPACE_ID,
    api_key=ARIZE_API_KEY,
    project_name=ARIZE_PROJECT_NAME,
)
Same outcome — Resource, Exporter, Span Processor, Tracer Provider all wired up — in much less code.

What register() Does Under the Hood

The convenience function handles four things for you. Each one has additional capabilities specific to OpenInference and Arize AX compared to the standard OTel SDK:
Component returned by register()What it adds beyond standard OTel
Tracer ProviderReturns a provider that hands out OITracer instances — a subclass of the OTel Tracer that reads OpenInference attributes from the OTel context. This is what makes the OpenInference context managers (using_session, using_user, using_metadata, etc.) actually attach attributes to spans.
Span ProcessorConfigured and pre-attached, ready to forward spans to the Arize AX–specific exporter.
Span ExporterAdds the headers needed to authenticate against the Arize AX collector and handles gRPC/HTTP transport correctly for your endpoint.
ResourceSets the project name automatically from your project_name argument.
For the canonical reference of every option, see Configure your tracer.

ArizeRoutingProcessor and Multi-Project Routing

Setting the project name at the Resource level means all traces from one application go to the same Arize AX project. That’s the right default for most apps. But more complex use cases need to send traces to different projects (or different Arize AX spaces entirely) based on span attributes or request metadata — for example, a multi-tenant app that wants each customer’s traces to land in their own project. The previous workarounds were:
  1. Spin up multiple Tracer Providers — but only one can be the global, so this gets awkward.
  2. Modify resource attributes at the Collector level with a transform processor — works, but adds operational complexity.
Arize added a cleaner path: ArizeRoutingProcessor plus the register_with_routing and set_routing_context helpers.

How Routing Works

Arize AX supports overriding the resource-level project name with a span attributearize.project.name. The ArizeRoutingProcessor also supports routing across Arize AX spaces via the arize.space_id span attribute. set_routing_context is a context manager that attaches both attributes to the OTel context, so you don’t have to set them manually on every span.

Configuring Routing

from arize.otel import register_with_routing, set_routing_context

tracer_provider = register_with_routing(api_key="ARIZE_API_KEY")
tracer = tracer_provider.get_tracer(__name__)

with set_routing_context(space_id="SPACE_ID", project_name="PROJECT_NAME"):
    with tracer.start_as_current_span("Root Span") as span:
        span.set_attributes({"input.value": "..."})
Every span created inside the set_routing_context block is routed to the specified space and project.
register_with_routing uses ARIZE_API_KEY from the environment if api_key isn’t passed. Both space_id and project_name must be set inside set_routing_context — otherwise routing won’t be applied.Python-only today. For JS/TS or Go apps — or routing logic the SDK can’t express — route at the OTel Collector layer instead.
For the practical setup, see Route Spans to Multiple Projects.

When to Use Which

Use caseRecommended approach
Single project, simple appregister(...)
Multiple projects from one app, per-request routingregister_with_routing(...) + set_routing_context(...)
Routing across many spaces in a shared-collector environmentOTel Collector with dynamic routing — see Advanced Patterns
Maximum control, custom processor pipelineRaw OTel — see Configure your tracer

Next step

You’ve covered every component on the OTel side. Time to learn what OpenInference adds on top — starting with the semantic conventions that make AI traces meaningful:

Next: OpenInference Semantic Conventions