# Copilot SDK 用の OpenTelemetry インストルメンテーション

このガイドでは、OpenTelemetry トレースを Copilot SDK アプリケーションに追加する方法について説明します。

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

## 組み込みのテレメトリのサポート

SDK には、CLI プロセスで OpenTelemetry を構成し、SDK と CLI の間で W3C トレース コンテキストを伝達するためのサポートが組み込まれています。 オプトインするクライアントを作成するときに `TelemetryConfig` を指定します。

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

<!-- docs-validate: skip -->

```typescript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient({
  telemetry: {
    otlpEndpoint: "http://localhost:4318",
  },
});
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

<!-- docs-validate: skip -->

```python
from copilot import CopilotClient

client = CopilotClient(
    telemetry={
        "otlp_endpoint": "http://localhost:4318",
    },
)
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

<!-- docs-validate: skip -->

```golang
client := copilot.NewClient(&copilot.ClientOptions{
    Telemetry: &copilot.TelemetryConfig{
        OTLPEndpoint: "http://localhost:4318",
    },
})
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

<!-- docs-validate: skip -->

```csharp
var client = new CopilotClient(new CopilotClientOptions
{
    Telemetry = new TelemetryConfig
    {
        OtlpEndpoint = "http://localhost:4318",
    },
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

var client = new CopilotClient(new CopilotClientOptions()
    .setTelemetry(new TelemetryConfig()
        .setOtlpEndpoint("http://localhost:4318"))
);
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

<!-- docs-validate: skip -->

```rust
use github_copilot_sdk::{Client, ClientOptions, TelemetryConfig};

let client = Client::start(ClientOptions::new()
    .with_telemetry(TelemetryConfig::new()
        .with_otlp_endpoint("http://localhost:4318"))
).await?;
```

</div>

</div>

### TelemetryConfig オプション

| オプション                      | Node.js          | Python            | Go               | .NET             | Java             | Rust              | 説明                                                             |
| -------------------------- | ---------------- | ----------------- | ---------------- | ---------------- | ---------------- | ----------------- | -------------------------------------------------------------- |
| OTLP エンドポイント               | `otlpEndpoint`   | `otlp_endpoint`   | `OTLPEndpoint`   | `OtlpEndpoint`   | `otlpEndpoint`   | `otlp_endpoint`   | OTLP HTTP エンドポイント URL                                          |
| OTLP プロトコル                 | `otlpProtocol`   | `otlp_protocol`   | `OTLPProtocol`   | `OtlpProtocol`   | `otlpProtocol`   | `otlp_protocol`   | すべてのシグナルの OTLP HTTP プロトコル: `"http/json"` または `"http/protobuf"` |
| ファイルパス                     | `filePath`       | `file_path`       | `FilePath`       | `FilePath`       | `filePath`       | `file_path`       | JSON 行トレース出力のファイル パス                                           |
| エクスポーターの種類                 | `exporterType`   | `exporter_type`   | `ExporterType`   | `ExporterType`   | `exporterType`   | `exporter_type`   |                                                                |
| `"otlp-http"` または `"file"` |                  |                   |                  |                  |                  |                   |                                                                |
| ソース名                       | `sourceName`     | `source_name`     | `SourceName`     | `SourceName`     | `sourceName`     | `source_name`     | 計装範囲名                                                          |
| コンテンツをキャプチャする              | `captureContent` | `capture_content` | `CaptureContent` | `CaptureContent` | `captureContent` | `capture_content` | メッセージの内容をキャプチャするかどうか                                           |

OTLP プロトコル フィールドは、すべての信号に対して CLI の `"otlp-http"` エクスポーターを構成します。 CLI の既定値を使用するように設定したままにするか、http 経由で protobuf をエクスポートする `"http/protobuf"` に設定します。

### トレース コンテキストの伝達

> **ほとんどのユーザーはこれを必要としません。** 上記の `TelemetryConfig` は、CLI からトレースを収集するために必要なすべてです。 このセクションで説明するトレース コンテキスト伝達は、独自の OpenTelemetry スパンを作成し、CLI のスパンと**同じ分散トレース**に表示するアプリケーションの**高度な機能**です。

SDK は、JSON-RPC ペイロードに W3C トレース コンテキスト (`traceparent`/`tracestate`) を伝達できるため、アプリケーションのスパンと CLI のスパンが 1 つの分散トレースにリンクされます。 これは、たとえば、アプリ内の「ツール呼び出しを処理」スパンが CLI の「ツールを実行」スパンの内側に入れ子になった状態で表示したい場合や、SDK 呼び出しをリクエスト処理スパンの子として表示したい場合に便利です。

トレースとあわせてコストの帰属を確認するには、`assistant.usage` イベントを購読し、`apiEndpoint`（`AssistantUsageApiEndpoint`）を確認して、そのターンで Chat Completions、Responses、または Anthropic Messages のいずれが使用されたかを確認します。[ストリーミング セッション イベント](/ja/copilot/how-tos/copilot-sdk/features/streaming-events) を参照してください。

#### SDK → CLI (送信)

**Node.js**の場合は、クライアント オプションに`onGetTraceContext`コールバックを指定します。 これは、アプリケーションで既に `@opentelemetry/api` を使用しており、スパンを CLI のスパンにリンクする場合にのみ必要です。 SDK は、RPC を `session.create`、 `session.resume`、および `session.send` する前に、このコールバックを呼び出します。

<!-- docs-validate: skip -->

```typescript
import { CopilotClient } from "@github/copilot-sdk";
import { propagation, context } from "@opentelemetry/api";

const client = new CopilotClient({
  telemetry: { otlpEndpoint: "http://localhost:4318" },
  onGetTraceContext: () => {
    const carrier: Record<string, string> = {};
    propagation.inject(context.active(), carrier);
    return carrier; // { traceparent: "00-...", tracestate: "..." }
  },
});
```

**Python**、**Go**、および **.NET** では、それぞれの OpenTelemetry/Activity API が構成されている場合、トレース コンテキストの挿入は自動的に行われます。コールバックは必要ありません。

#### CLI → SDK（インバウンド）

CLI がツール ハンドラーを呼び出すと、CLI のスパンからの `traceparent` と `tracestate` は、すべての言語で使用できます。

* **Go**: `ToolInvocation.TraceContext` フィールドは、すでに復元されたトレースを含む `context.Context` です。これをスパンの親としてそのまま使用してください。
* **Python**: トレース コンテキストは、`trace_context()` を介してハンドラーの周囲に自動的に復元されます。子スパンは CLI のスパンに自動的に親されます。
* **.NET**: トレース コンテキストは自動的に復元され、`RestoreTraceContext()`子`Activity`インスタンスは自動的に CLI のスパンに紐付けられます。
* **Node.js**: SDK には OpenTelemetry 依存関係がないため、 `traceparent` と `tracestate` は、 `ToolInvocation` オブジェクトに生の文字列として渡されます。 必要に応じて、コンテキストを手動で復元します。

<!-- docs-validate: skip -->

```typescript
import { defineTool } from "@github/copilot-sdk";
import { propagation, context, trace } from "@opentelemetry/api";

const myTool = defineTool("my-tool", {
  description: "Do work",
  handler: async (args, invocation) => {
    // Restore the CLI's trace context as the active context
    const carrier = {
      traceparent: invocation.traceparent,
      tracestate: invocation.tracestate,
    };
    const parentCtx = propagation.extract(context.active(), carrier);

    // Create a child span under the CLI's span
    const tracer = trace.getTracer("my-app");
    return context.with(parentCtx, () =>
      tracer.startActiveSpan("my-tool", async (span) => {
        try {
          const result = await doWork(args);
          return result;
        } finally {
          span.end();
        }
      })
    );
  },
});

// Tool handlers are registered when the session is created.
const session = await client.createSession({ tools: [myTool] });
```

### 言語ごとの依存関係

| Language | 依存関係                                 | メモ                                                                                               |
| -------- | ------------------------------------ | ------------------------------------------------------------------------------------------------ |
| Node.js  | —                                    | 依存関係なし。外向き伝播用の`onGetTraceContext`コールバックを提供する                                                     |
| Python   | `opentelemetry-api`                  | を使用してインストールする `pip install copilot-sdk[telemetry]`                                               |
| Go       | `go.opentelemetry.io/otel`           | 必要な依存関係                                                                                          |
| .NET     | —                                    | 組み込みの `System.Diagnostics.Activity` を使用する                                                        |
| Java     | `io.opentelemetry:opentelemetry-api` | SDK ベースのセットアップにこの依存関係を追加します。OpenTelemetry Java エージェントまたは SDK が構成されている場合、トレース コンテキストの挿入は自動的に行われます |

## References

* [OpenTelemetry GenAI セマンティック規則](https://opentelemetry.io/docs/specs/semconv/gen-ai/)
* [OpenTelemetry MCP セマンティック規則](https://opentelemetry.io/docs/specs/semconv/gen-ai/mcp/)
* [OpenTelemetry Python SDK](https://opentelemetry.io/docs/instrumentation/python/)
* [Copilot SDK ドキュメント](https://github.com/github/copilot-sdk)