> ## Documentation Index
> Fetch the complete documentation index at: https://arize-ax.mintlify.site/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenLLMetry & Traceloop

> Trace LLM apps with Traceloop's OpenLLMetry SDK, convert spans to OpenInference, and send them to Arize AX for LLM observability.

[OpenLLMetry](https://github.com/traceloop/openllmetry) is Traceloop's open-source observability package that auto-instruments 20+ LLM providers and frameworks with OpenTelemetry. The [Traceloop SDK](https://www.traceloop.com/docs/openllmetry/introduction) (`traceloop-sdk`) is the one-line `Traceloop.init()` wrapper that activates those instrumentors — the two are the same integration, so this page covers both. Arize AX ingests their spans by converting them to OpenInference with the [`openinference-instrumentation-openllmetry`](https://github.com/Arize-ai/openinference/tree/main/python/instrumentation/openinference-instrumentation-openllmetry) span processor.

## Prerequisites

* Python 3.9+
* An Arize AX account ([sign up](https://arize.com/sign-up/))
* An `OPENAI_API_KEY` from the [OpenAI Platform](https://platform.openai.com/api-keys)

## Launch Arize AX

1. Sign in to your [Arize AX account](https://app.arize.com/).
2. From **Space Settings**, copy your **Space ID** and **API Key**. You will set them as `ARIZE_SPACE_ID` and `ARIZE_API_KEY` below.

## Install

```bash theme={null}
pip install traceloop-sdk openinference-instrumentation-openllmetry arize-otel opentelemetry-exporter-otlp-proto-grpc openai
```

## Configure credentials

<Tabs>
  <Tab title="OpenAI">
    ```bash theme={null}
    export ARIZE_SPACE_ID="<your-space-id>"
    export ARIZE_API_KEY="<your-api-key>"
    export ARIZE_PROJECT_NAME="openllmetry-tracing-example"
    export OPENAI_API_KEY="<your-openai-api-key>"
    ```
  </Tab>
</Tabs>

OpenLLMetry auto-instruments any provider it supports the same way — swap the OpenAI packages and client below for [another supported provider](https://www.traceloop.com/docs/openllmetry/tracing/supported) and the wiring is unchanged.

## Setup tracing

```python theme={null}
# instrumentation.py
import os

import grpc
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from openinference.instrumentation.openllmetry import OpenInferenceSpanProcessor
from traceloop.sdk import Traceloop

project_name = os.environ.get("ARIZE_PROJECT_NAME", "openllmetry-tracing-example")

# Export spans to Arize AX over OTLP/gRPC.
arize_exporter = OTLPSpanExporter(
    endpoint="otlp.arize.com:443",
    headers={
        "authorization": f"Bearer {os.environ['ARIZE_API_KEY']}",
        "arize-space-id": os.environ["ARIZE_SPACE_ID"],
        "arize-interface": "python",
        "user-agent": "arize-python",
    },
    compression=grpc.Compression.Gzip,
)

# Traceloop/OpenLLMetry emits OpenTelemetry spans. OpenInferenceSpanProcessor
# converts them to OpenInference before the exporter ships them to Arize AX, so
# it must run before the exporting processor in the list below.
Traceloop.init(
    app_name=project_name,
    disable_batch=True,
    processor=[OpenInferenceSpanProcessor(), SimpleSpanProcessor(arize_exporter)],
    resource_attributes={
        "openinference.project.name": project_name,
        "model_id": project_name,
    },
)

print("Arize AX tracing initialized for OpenLLMetry.")
```

<Note>
  Prefer to wire up individual instrumentors instead of the Traceloop SDK? Install the specific OpenLLMetry instrumentor (e.g. `opentelemetry-instrumentation-openai`), then instrument it against a tracer provider that carries the `OpenInferenceSpanProcessor` — the conversion step is the same.
</Note>

## Run OpenLLMetry

```python theme={null}
# example.py

# Importing instrumentation first runs Traceloop.init() and activates
# OpenLLMetry's auto-instrumentation before the OpenAI client is used.
from instrumentation import project_name  # noqa: F401

from openai import OpenAI

# The client reads OPENAI_API_KEY from the environment.
client = OpenAI()

response = client.chat.completions.create(
    model="gpt-5.4-mini",
    messages=[
        {"role": "user", "content": "Write a haiku about observability."},
    ],
)

print(response.choices[0].message.content)
```

### Expected output

```text wrap theme={null}
Arize AX tracing initialized for OpenLLMetry.
Logs whisper softly,
metrics rise like morning mist —
truth in every span.
```

## Verify in Arize AX

1. Open your Arize AX space and select project **`openllmetry-tracing-example`**.
2. You should see a new trace within \~30 seconds containing an `openai.chat` span with `openinference.span.kind` set to `LLM`, the prompt and response, and token usage attached.
3. If no traces appear, confirm `ARIZE_SPACE_ID`, `ARIZE_API_KEY`, and `OPENAI_API_KEY` are exported in the shell that ran the example.

### Check from the skill, CLI, or SDK

Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.

<Tabs>
  <Tab title="Arize skill (agent)">
    Install the [Arize Skills](https://github.com/Arize-ai/arize-skills) plugin and let your coding agent check for you:

    ```bash theme={null}
    npx skills add Arize-ai/arize-skills
    ```

    Then prompt your agent:

    > Use the `arize-trace` skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.
  </Tab>

  <Tab title="AX CLI">
    Export recent spans for your project — any rows mean traces are landing:

    ```bash theme={null}
    ax spans export "$ARIZE_PROJECT_NAME" --space "$ARIZE_SPACE_ID" \
      --limit 5 --stdout | jq 'length'
    ```

    A non-zero count confirms spans reached Arize AX. Run `ax auth login` first if you have not authenticated. See the [`ax spans` reference](/docs/api-clients/cli/spans).
  </Tab>

  <Tab title="SDK">
    Query the project's spans and check that at least one came back.

    <CodeGroup>
      ```python Python theme={null}
      import os
      from arize import ArizeClient

      client = ArizeClient(api_key=os.environ["ARIZE_API_KEY"])
      resp = client.spans.list(
          project=os.environ["ARIZE_PROJECT_NAME"],
          space=os.environ["ARIZE_SPACE_ID"],
          limit=5,
      )
      count = len(resp.spans)
      print(
          f"{count} span(s) found" if count else "No spans yet — recheck setup"
      )
      ```

      ```typescript TypeScript theme={null}
      // Reads ARIZE_API_KEY from the environment.
      import { listSpans } from "@arizeai/ax-client";

      const { data: spans } = await listSpans({
        project: process.env.ARIZE_PROJECT_NAME!,
        space: process.env.ARIZE_SPACE_ID!,
        limit: 5,
      });
      const count = spans.length;
      console.log(
        count ? `${count} span(s) found` : "No spans yet — recheck setup",
      );
      ```

      ```go Go theme={null}
      client, err := arize.NewClient(
          arize.Config{APIKey: os.Getenv("ARIZE_API_KEY")},
      )
      if err != nil {
          log.Fatal(err)
      }
      resp, err := client.Spans.List(ctx, spans.ListRequest{
          Project: os.Getenv("ARIZE_PROJECT_NAME"),
          Space:   os.Getenv("ARIZE_SPACE_ID"),
          Limit:   5,
      })
      if err != nil {
          log.Fatal(err)
      }
      fmt.Printf("%d span(s) found\n", len(resp.Spans))
      ```
    </CodeGroup>

    SDK span references: [Python](/docs/api-clients/python/version-8/client-resources/spans) · [TypeScript](/docs/api-clients/typescript/version-1/client-resources/spans) · [Go](/docs/api-clients/go/version-2/client-resources/spans).
  </Tab>
</Tabs>

## Resources

* [OpenLLMetry on GitHub](https://github.com/traceloop/openllmetry)
* [Traceloop SDK documentation](https://www.traceloop.com/docs/openllmetry/introduction)
* [OpenInference OpenLLMetry instrumentor](https://github.com/Arize-ai/openinference/tree/main/python/instrumentation/openinference-instrumentation-openllmetry)
