sdk changedmanage-claude/opentelemetry/sdk
Nearest release: v2.1.300, published 4 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
## 1. Install the SDK ## 2. Register a tracer provider ## 3. Send spans to your observability platform ## 4. Configure the SDK ## Next steps ## Tracing a stream ## Tracing a Managed Agents self-hosted sandbox ## Trace context and baggage ## Troubleshooting
The whole hunk
647 lines, new pageA whole new page. There's nothing to diff it against, so here is what it says.
---
title: Use OpenTelemetry with the Claude SDK
url: https://platform.claude.com/docs/en/manage-claude/opentelemetry/sdk
description: Trace each request that the Claude SDK sends and each tool that its tool runner runs, and send the spans to your observability platform.
featureMetadata:
topic:
title: OpenTelemetry
url: https://platform.claude.com/docs/en/manage-claude/opentelemetry
status: beta
supportedPlatforms:
Claude API: beta
Claude Platform on AWS: beta
Amazon Bedrock: beta
Google Cloud: beta
Microsoft Foundry: beta
rows:
- label: Works with
value: Messages API, Claude Managed Agents
---
With OpenTelemetry, the Claude SDK can emit a span for each request that it sends and each tool use that the [tool runner](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner) runs. You can view these spans in your observability platform, nested in your own traces.
The SDK emits spans in your application. Your application's OpenTelemetry exporter sends them to your observability platform.
<Note>
During the beta, the SDK options and the span schema can change in ways that break your code, your queries, or your dashboards. For example, a new version of the SDK can rename a span, an attribute, an option, or an environment variable. Pin the SDK version in your dependencies to choose when you adopt the changes.
</Note>
## 1. Install the SDK
Install or upgrade to the latest version of the Claude SDK:
<Tabs>
<Tab title="Python">
```bash
pip install --upgrade anthropic
```
If your application doesn't use the OpenTelemetry SDK yet, install it with a console exporter, which you use in the next step to print spans:
```bash
pip install opentelemetry-sdk
```
</Tab>
<Tab title="TypeScript">
```bash
npm install @anthropic-ai/sdk@latest
```
If your application doesn't use the OpenTelemetry SDK yet, install it with a console exporter, which you use in the next step to print spans:
```bash
npm install @opentelemetry/sdk-trace-node
```
</Tab>
<Tab title="C#">
```bash
dotnet add package Anthropic
```
If your application doesn't use the OpenTelemetry SDK yet, install it with a console exporter, which you use in the next step to print spans:
```bash
dotnet add package OpenTelemetry.Exporter.Console
```
</Tab>
<Tab title="Go">
```bash
go get github.com/anthropics/anthropic-sdk-go@latest
```
If your application doesn't use the OpenTelemetry SDK yet, install it with a console exporter, which you use in the next step to print spans:
```bash
go get go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/exporters/stdout/stdouttrace
```
</Tab>
<Tab title="Java">
Add the Claude SDK to your dependencies, or update it to at least the following version if your build file already declares it:
<CodeGroup exclude="shell, python, typescript, csharp, go, php, ruby">
```kotlin Gradle
implementation("com.anthropic:anthropic-java:2.72.0")
```
```xml Maven
<dependency>
<groupId>com.anthropic</groupId>
<artifactId>anthropic-java</artifactId>
<version>2.72.0</version>
</dependency>
```
</CodeGroup>
If your application doesn't use the OpenTelemetry SDK yet, install it with a console exporter, which you use in the next step to print spans. Add `io.opentelemetry:opentelemetry-sdk` and `io.opentelemetry:opentelemetry-exporter-logging` to your build, both at the latest version on [Maven Central](https://central.sonatype.com/artifact/io.opentelemetry/opentelemetry-sdk).
</Tab>
<Tab title="PHP">
```bash
composer require "anthropic-ai/sdk" "guzzlehttp/guzzle:^7"
```
If your application doesn't use the OpenTelemetry SDK yet, install it with a console exporter, which you use in the next step to print spans:
```bash
composer require open-telemetry/sdk
```
</Tab>
<Tab title="Ruby">
If your `Gemfile` doesn't list `anthropic` yet, add the gem:
```bash
bundle add anthropic
```
If your `Gemfile` already lists `anthropic`, update the gem:
```bash
bundle update anthropic
```
If your application doesn't use the OpenTelemetry SDK yet, install it with a console exporter, which you use in the next step to print spans:
```bash
bundle add opentelemetry-sdk
```
</Tab>
</Tabs>
## 2. Register a tracer provider
A *tracer provider* is the OpenTelemetry object that creates spans and passes them to your exporter. The SDK uses the tracer provider that your application registers, so your SDK calls stay the same. Register it before the first call that you want to trace.
The following example registers a tracer provider that prints each span to the console and then makes one call. Use it to see spans before you connect an observability platform:
<CodeGroup exclude="shell">
```python Python
from anthropic import Anthropic
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
# Register a tracer provider that prints each span to the console.
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(provider)
client = Anthropic()
message = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(message.content)
```
```typescript TypeScript
import Anthropic from "@anthropic-ai/sdk";
import {
ConsoleSpanExporter,
NodeTracerProvider,
SimpleSpanProcessor
} from "@opentelemetry/sdk-trace-node";
// Register a tracer provider that prints each span to the console.
const provider = new NodeTracerProvider({
spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())]
});
// register() also installs the context manager, which lets the SDK spans nest under your spans.
provider.register();
const client = new Anthropic();
const message = await client.messages.create({
model: "claude-opus-5-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello, Claude" }]
});
console.log(message.content);
```
```csharp C#
using Anthropic;
using Anthropic.Models.Messages;
using OpenTelemetry;
using OpenTelemetry.Trace;
// Register a tracer provider that prints each span to the console.
// The SDK emits its spans from the source com.anthropic.sdk.csharp. Add com.anthropic.sdk.csharp*
// instead to include the SDK's clients for cloud platforms.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("com.anthropic.sdk.csharp")
.AddConsoleExporter()
.Build();
AnthropicClient client = new();
var message = await client.Messages.Create(new MessageCreateParams
{
Model = Model.ClaudeOpus5_5,
MaxTokens = 1024,
Messages = [new() { Role = Role.User, Content = "Hello, Claude" }],
});
Console.WriteLine(message);
```
```go Go
package main
import (
"context"
"fmt"
"github.com/anthropics/anthropic-sdk-go"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
"go.opentelemetry.io/otel/propagation"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
func main() {
ctx := context.Background()
// Register a tracer provider that prints each span to the console.
exporter, err := stdouttrace.New(stdouttrace.WithPrettyPrint())
if err != nil {
panic(err)
}
provider := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exporter))
defer provider.Shutdown(ctx)
otel.SetTracerProvider(provider)
// OpenTelemetry for Go doesn't register a propagator by default, so
// register the W3C trace context propagator.
otel.SetTextMapPropagator(propagation.TraceContext{})
client := anthropic.NewClient()
message, err := client.Messages.New(ctx, anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus5_5,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Hello, Claude")),
},
})
if err != nil {
panic(err)
}
fmt.Println(message.Content)
}
```
```java Java
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
void main() {
// Register a tracer provider that writes each span to the log.
var tracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
.build();
OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
// OpenTelemetry for Java doesn't register a propagator when you build
// it in code, so register the W3C trace context propagator.
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal();
var client = AnthropicOkHttpClient.fromEnv();
var message = client.messages().create(MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(1024)
.addUserMessage("Hello, Claude")
.build());
IO.println(message.content());
tracerProvider.close();
}
```
```php PHP
use Anthropic\Client;
use Anthropic\Messages\Model;
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
use OpenTelemetry\SDK\Sdk;
use OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporterFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
Cut at 300 lines. The page has the rest.
No line in this hunk matches that.