> ## Documentation Index
> Fetch the complete documentation index at: https://platform.atlan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect tracing integrations

> Send framework, model, tool, and agent spans to Agent Registry through one OpenTelemetry pipeline.

The Atlan SDK accepts native SDK spans, third-party OpenTelemetry spans, and
framework callback spans through one exporter. You do not need a separate
trace model for each provider.

Choose the narrowest integration path your stack supports:

| Path                        | Use it when                                                        | What you add                                                   |
| --------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------- |
| Native OpenTelemetry        | The library already emits OTel spans                               | Share Atlan's provider or processor, or point OTLP at Registry |
| Python auto-instrumentation | An installed AI instrumentor exposes the standard OTel entry point | `auto_instrument()` once at startup                            |
| Framework adapter           | Atlan ships a tested callback or native telemetry adapter          | Add the callback or wrapper to the framework call              |
| Manual boundary             | The library emits no usable spans                                  | Wrap its top-level call with `traced` / `wrapTraced`           |

All four paths use asynchronous batch export by default. Call `flush()` before
a short-lived process exits. `Eval` does this automatically, then reads every
case trace back through the experiment filter before it writes results and
finalizes a run. Registry derives the durable score summary during finalization.

`initLogger` captures every OpenTelemetry scope by default. This includes any
HTTP, database, or application instrumentors already attached to the same
provider. Pass `captureAll: false` / `capture_all=False` to return to Atlan's
AI-focused allowlist, and apply [privacy controls](/sdk/privacy) before sending
third-party spans that may contain protected content.

## Discover installed Python instrumentors

`auto_instrument()` discovers the standard `opentelemetry_instrumentor` entry
points already installed in your environment. It enables only recognized AI
instrumentors and does not begin tracing unrelated database or web-framework
libraries.

Call it before importing provider clients, then initialize the logger:

```python theme={null}
from atlanai.tracing import auto_instrument, init_logger

report = auto_instrument()
logger = init_logger(project_name="support-agent")

print("instrumented:", report.instrumented)
print("failed:", report.failed)
```

The Atlan package does not install every vendor instrumentor. Install the OTel
instrumentation package approved for your provider, then let
`auto_instrument()` discover it. Disable one installed integration with a
Braintrust-compatible flag such as `auto_instrument(openai=False)`.

<Warning>
  Treat `report.failed` as a deployment failure when complete traces are a
  requirement. A running application does not prove that its provider spans
  were instrumented.
</Warning>

## Vercel AI SDK

`wrapAISDK` injects the AI SDK's native `experimental_telemetry` option into
generation, streaming, embedding, reranking, and agent calls. It preserves
telemetry metadata supplied by the caller and leaves unrelated exports
untouched.

```typescript theme={null}
import * as ai from "ai";
import { initLogger, wrapAISDK } from "@atlanai/sdk/tracing";

const logger = initLogger({ projectName: "support-agent" });
const tracedAI = wrapAISDK(ai, {
  logger,
  metadata: { component: "answer-generation" },
});

try {
  const result = await tracedAI.generateText({
    model,
    prompt: "What is 2+2?",
  });
  console.log(result.text);
} finally {
  await logger.flush();
}
```

If you prefer not to wrap the module, pass telemetry to one call:

```typescript theme={null}
import { aiTelemetry } from "@atlanai/sdk/tracing";

const result = await ai.generateText({
  model,
  prompt,
  experimental_telemetry: aiTelemetry({ functionId: "answer" }),
});
```

Initialize the logger before the first AI SDK call. If a call already contains
a tracer, `wrapAISDK` preserves it by default. Pass `replaceTracer: true` only
when Atlan should replace that tracer.

## LangChain and LangGraph

The Python callback maps framework run IDs, parents, model usage, tool calls,
errors, and LangGraph interrupt/resume flow into one trace tree.

```python theme={null}
from atlanai.tracing import init_logger
from atlanai.tracing.langchain import CallbackHandler

logger = init_logger(project_name="support-agent")
handler = CallbackHandler()

try:
    result = graph.invoke(
        {"messages": [{"role": "user", "content": "What is 2+2?"}]},
        config={"callbacks": [handler]},
    )
finally:
    logger.flush()
```

For LangChain.js, use its OpenTelemetry integration when available. Otherwise,
wrap `graph.invoke` with `wrapTraced` to preserve the agent boundary.

## Share an application-owned OpenTelemetry provider

Python automatically reuses a global SDK `TracerProvider` that your
application registered first. You can also pass it explicitly:

```python theme={null}
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from atlanai.tracing import init_logger

provider = TracerProvider(
    resource=Resource.create({"service.name": "support-agent"}),
)
trace.set_tracer_provider(provider)
logger = init_logger(
    project_name="support-agent",
    tracer_provider=provider,
)
```

OpenTelemetry JS allows only one global provider and does not let another SDK
mutate it later. If your application owns that provider, initialize Atlan in
isolated mode and add its processor when constructing the application
provider:

```typescript theme={null}
import { resourceFromAttributes } from "@opentelemetry/resources";
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import { initLogger } from "@atlanai/sdk/tracing";

const logger = initLogger({
  projectName: "support-agent",
  isolated: true,
});

if (!logger.client.spanProcessor) {
  throw new Error("Atlan tracing is disabled");
}

const provider = new NodeTracerProvider({
  resource: resourceFromAttributes({ "service.name": "support-agent" }),
  spanProcessors: [logger.client.spanProcessor],
});
provider.register();
```

Create provider and framework clients after this setup. Otherwise, those
clients may retain a tracer from a different provider and their spans will not
reach Registry.

## Send direct OTLP

Java, Ruby, Go, sidecars, and other OpenTelemetry runtimes can send OTLP/HTTP
protobuf without either Atlan SDK:

```bash theme={null}
export ATLAN_BASE_URL="https://agentgateway.atlan.engineering"
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="${ATLAN_BASE_URL}/otel/v1/traces"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer%20${ATLAN_API_KEY},X-Atlan-Workspace-Id=${ATLAN_WORKSPACE_ID}"
```

Populate these values through an approved secret store. Do not put headers in
source code, container images, or deployment manifests.

## Wrap an unsupported framework

Manual wrapping guarantees the agent boundary, input, output, latency, and
failure. Calls from instrumented providers inside the wrapper become child
spans automatically.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { wrapTraced } from "@atlanai/sdk/tracing";

  const runAgent = wrapTraced(
    agent.run.bind(agent),
    { name: "agent.run", type: "task" },
  );

  const result = await runAgent(input);
  ```

  ```python Python theme={null}
  from atlanai.tracing import traced

  @traced(name="agent.run", type="task")
  def run_agent(input):
      return agent.run(input)
  ```
</CodeGroup>

Manual wrapping cannot invent model, tool, token, or cost details that the
framework does not expose. Add child spans or `span.update(...)` calls for
those fields when you own the call site.

## Integration coverage

Coverage describes the delivery contract, not every version of a third-party
package:

| Level      | Meaning                                                                                                   |
| ---------- | --------------------------------------------------------------------------------------------------------- |
| Certified  | An executable Atlan SDK test covers the adapter contract                                                  |
| Compatible | The integration emits OpenTelemetry or uses a stable callback contract consumed by one of the paths above |
| Manual     | Wrap the framework boundary explicitly                                                                    |

### Tracing libraries

| Integration           | Level      | Recommended path                                           |
| --------------------- | ---------- | ---------------------------------------------------------- |
| OpenTelemetry         | Certified  | Shared provider, Atlan processor, or direct OTLP           |
| Temporal              | Compatible | OpenTelemetry or direct OTLP                               |
| Vercel AI SDK         | Certified  | `wrapAISDK` or `aiTelemetry`                               |
| OpenRouter SDK        | Compatible | Python auto-instrumentation or manual boundary             |
| LangChain             | Certified  | Python `CallbackHandler`; OpenTelemetry for other runtimes |
| LangChain4j           | Compatible | Direct OTLP                                                |
| LangSmith             | Manual     | `traced` or `wrapTraced`                                   |
| LlamaIndex            | Compatible | Python auto-instrumentation or OpenTelemetry               |
| Agno                  | Compatible | Python auto-instrumentation or OpenTelemetry               |
| Apollo GraphQL        | Compatible | OpenTelemetry                                              |
| Cloudflare Workers AI | Compatible | OpenTelemetry or manual boundary                           |
| DSPy                  | Compatible | Python auto-instrumentation or OpenTelemetry               |
| Instructor            | Compatible | Python auto-instrumentation or OpenTelemetry               |
| LiteLLM               | Compatible | Python auto-instrumentation or OpenTelemetry               |
| Ruby LLM              | Compatible | Direct OTLP or manual boundary                             |
| Spring AI             | Compatible | Direct OTLP                                                |
| Traceloop             | Compatible | Shared OpenTelemetry provider or direct OTLP               |
| TrueFoundry           | Compatible | Shared OpenTelemetry provider or direct OTLP               |

### Agent frameworks

| Integration        | Level      | Recommended path                             |
| ------------------ | ---------- | -------------------------------------------- |
| OpenAI Agents SDK  | Compatible | Python auto-instrumentation or OpenTelemetry |
| Claude Agent SDK   | Manual     | `traced` or `wrapTraced`                     |
| Pi Coding Agent    | Manual     | `traced` or `wrapTraced`                     |
| Deep Agents        | Compatible | LangChain callback                           |
| LangGraph          | Certified  | Python `CallbackHandler`                     |
| CrewAI             | Compatible | Python auto-instrumentation or OpenTelemetry |
| AutoGen            | Compatible | OpenTelemetry                                |
| AgentScope         | Compatible | Python auto-instrumentation or OpenTelemetry |
| Google ADK         | Compatible | Python auto-instrumentation or OpenTelemetry |
| LiveKit Agents     | Compatible | Python auto-instrumentation or OpenTelemetry |
| Mastra             | Compatible | OpenTelemetry                                |
| Pipecat            | Compatible | Python auto-instrumentation or OpenTelemetry |
| Pydantic AI        | Compatible | Python auto-instrumentation or OpenTelemetry |
| Strands            | Compatible | Python auto-instrumentation or OpenTelemetry |
| Cloudflare Agents  | Compatible | OpenTelemetry or manual boundary             |
| Cloudflare AI Chat | Compatible | `wrapAISDK` or `aiTelemetry`                 |

<Note>
  Run one representative request after every framework or instrumentor
  upgrade. Confirm the root, provider call, tool calls, usage, and expected
  parent relationships in Agent Registry before promoting the build.
</Note>

## Preserve evaluation joins

Third-party spans created inside an `Eval` task inherit
`atlan.eval.experiment_id` from the active context. The experiment result then
stores the case's root `trace_id`. Bench filters use the experiment attribute;
case drill-down uses the result-to-trace join.

If you run your own harness, execute it inside `run.trace()` in Python or
`propagateAttributes(run.traceOptions, fn)` in TypeScript. Flush and verify the
traces, upload complete result rows with their numeric score snapshots, then
mark the experiment `completed` with one update. Consume the returned
experiment's `summary`; no separate summarize request is needed.

## Next steps

<CardGroup cols={2}>
  <Card title="Run evaluations" icon="flask" href="/sdk/evaluations">
    Create one trace and durable result for every case.
  </Card>

  <Card title="Privacy controls" icon="shield" href="/sdk/privacy">
    Suppress or mask content from first-party and third-party spans.
  </Card>

  <Card title="Serverless delivery" icon="bolt" href="/sdk/serverless">
    Keep asynchronous exports alive before a function freezes.
  </Card>

  <Card title="Verify traces" icon="check" href="/guides/traces/send-and-verify">
    Confirm ingestion and parent-child structure end to end.
  </Card>
</CardGroup>
