Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Arize ai Phoenix TracerProvider Instrumentation

From Leeroopedia
Knowledge Sources
Domains AI Observability, OpenTelemetry, LLM Instrumentation
Last Updated 2026-02-14 00:00 GMT

Overview

Concrete tool for instrumenting LLM applications with OpenTelemetry tracing provided by the phoenix.otel module's TracerProvider class and the register() function's auto-instrumentation capability.

Description

The Phoenix TracerProvider extends openinference.instrumentation.TracerProvider (which itself extends opentelemetry.sdk.trace.TracerProvider) with Phoenix-aware defaults. It serves as the foundation for both manual and automatic instrumentation of LLM applications.

Key behaviors:

  • Default processor creation: When an endpoint is provided (or inferred from PHOENIX_COLLECTOR_ENDPOINT), the TracerProvider automatically creates a default SimpleSpanProcessor with an appropriate exporter (HTTP or gRPC) based on the endpoint URL pattern.
  • Processor replacement: Calling add_span_processor() on a TracerProvider that has a default processor will first shut down and remove the default processor before adding the new one. This prevents duplicate span export.
  • Resource management: Automatically creates an OTel Resource with the openinference.project.name attribute set from the environment if no explicit resource is provided.
  • Auto-instrumentation: The register(auto_instrument=True) pathway calls _auto_instrument_installed_openinference_libraries(), which discovers all installed OpenInference instrumentors via Python entry points and activates them.

Usage

Use these APIs when:

  • You need manual instrumentation with fine-grained control: instantiate TracerProvider directly, obtain a tracer, and create spans explicitly.
  • You want automatic instrumentation: call register(auto_instrument=True) to discover and activate all installed OpenInference instrumentors.
  • You need to combine both approaches: use auto-instrumentation for framework calls and manual instrumentation for custom business logic.

Code Reference

Source Location

  • Repository: Phoenix
  • File: packages/phoenix-otel/src/phoenix/otel/otel.py
    • TracerProvider class: lines 201-296
    • _auto_instrument_installed_openinference_libraries(): lines 805-821

Signature

class TracerProvider(_TracerProvider):
    def __init__(
        self,
        *args: Any,
        endpoint: Optional[str] = None,
        protocol: Optional[Literal["http/protobuf", "grpc"]] = None,
        verbose: bool = True,
        **kwargs: Any,
    ):
        ...

    def add_span_processor(
        self,
        *args: Any,
        replace_default_processor: bool = True,
        **kwargs: Any,
    ) -> None:
        ...

Auto-instrumentation helper:

def _auto_instrument_installed_openinference_libraries(
    tracer_provider: TracerProvider,
) -> None:
    ...

Import

from phoenix.otel import TracerProvider
from phoenix.otel import register

I/O Contract

Inputs (TracerProvider.__init__)

Name Type Required Description
*args Any No Positional arguments forwarded to the base opentelemetry.sdk.trace.TracerProvider.
endpoint Optional[str] No Collector endpoint URL. If provided, a default SimpleSpanProcessor and exporter are created automatically. Falls back to PHOENIX_COLLECTOR_ENDPOINT env var, then http://localhost:6006.
protocol Optional[Literal["http/protobuf", "grpc"]] No Explicit transport protocol. If not set, inferred from the endpoint URL (paths containing /v1/traces use HTTP; port 4317 uses gRPC).
verbose bool No If True (default), prints tracing configuration details to stdout.
**kwargs Any No Keyword arguments forwarded to the base TracerProvider, including resource for custom OTel resource attributes.

Inputs (add_span_processor)

Name Type Required Description
*args Any Yes Positional arguments forwarded to the base add_span_processor (typically a SpanProcessor instance).
replace_default_processor bool No If True (default), shuts down and removes any default processor before adding the new one.
**kwargs Any No Additional keyword arguments forwarded to the base method.

Outputs

Name Type Description
TracerProvider instance TracerProvider A configured tracer provider from which tracers can be obtained via get_tracer().
tracer Tracer Obtained via tracer_provider.get_tracer(__name__), used to create spans.

Usage Examples

Manual Instrumentation

from phoenix.otel import TracerProvider

# Create a TracerProvider that auto-configures endpoint from env
tracer_provider = TracerProvider()

# Obtain a tracer
tracer = tracer_provider.get_tracer(__name__)

# Create spans manually
with tracer.start_as_current_span("process-user-query") as span:
    span.set_attribute("input.value", "What is the capital of France?")

    with tracer.start_as_current_span("llm-call") as child_span:
        response = call_llm(query)
        child_span.set_attribute("output.value", response)
        child_span.set_attribute("llm.token_count.total", token_count)

Automatic Instrumentation via register()

from phoenix.otel import register

# Auto-discover and instrument all installed OpenInference libraries
tracer_provider = register(auto_instrument=True)

# Now all calls to instrumented libraries (OpenAI, LangChain, etc.)
# automatically produce spans
import openai
client = openai.OpenAI()
# This call is automatically traced
response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello!"}],
)

Custom TracerProvider with Explicit Endpoint

from phoenix.otel import TracerProvider
from opentelemetry.sdk.resources import Resource

tracer_provider = TracerProvider(
    resource=Resource.create({"openinference.project.name": "my-project"}),
    endpoint="http://localhost:6006/v1/traces",
    protocol="http/protobuf",
)

tracer = tracer_provider.get_tracer("my-app")

Combining Auto and Manual Instrumentation

from phoenix.otel import register

# Auto-instrument framework calls
tracer_provider = register(
    auto_instrument=True,
    project_name="my-agent",
)

# Also add manual spans for custom logic
tracer = tracer_provider.get_tracer(__name__)

with tracer.start_as_current_span("agent-reasoning-step"):
    # Custom business logic that is not auto-instrumented
    decision = evaluate_next_action(context)

Replacing the Default Processor

from phoenix.otel import TracerProvider, BatchSpanProcessor

# TracerProvider creates a default SimpleSpanProcessor
tracer_provider = TracerProvider()

# Replace the default with a BatchSpanProcessor for production
batch_processor = BatchSpanProcessor(
    endpoint="https://my-collector.com/v1/traces",
    headers={"Authorization": "Bearer my-token"},
)
tracer_provider.add_span_processor(batch_processor)
# The default SimpleSpanProcessor is automatically shut down and removed

Related Pages

Implements Principle

Requires Environment

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment