# 코필로트 SDK용 OpenTelemetry 계측

이 가이드에서는 Copilot SDK 애플리케이션에 OpenTelemetry 추적을 추가하는 방법을 보여 줍니다.

<!-- 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' 설정 옵션

| Option                    | Node.JS          | Python            | Go               | .NET             | Java             | 러스트               | 설명                                                           |
| ------------------------- | ---------------- | ----------------- | ---------------- | ---------------- | ---------------- | ----------------- | ------------------------------------------------------------ |
| 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 범위가 하나의 분산 추적에 연결되도록 할 수 있습니다. 예를 들어 CLI의 "실행 도구" 범위 내에 중첩된 앱에서 "핸들 도구 호출" 범위를 보거나 요청 처리 범위의 자식으로 SDK 호출을 표시하려는 경우에 유용합니다.

추적과 함께 비용 특성을 확인하려면 `assistant.usage` 이벤트를 구독하고 `apiEndpoint`(`AssistantUsageApiEndpoint`)를 확인하여 해당 턴에서 채팅 자동 완료, 응답 또는 Anthropic 메시지가 사용되었는지 확인하십시오. 자세한 내용은 [스트리밍 세션 이벤트](/ko/copilot/how-tos/copilot-sdk/features/streaming-events)을 참조하십시오.

#### SDK → CLI(아웃바운드)

**Node.js**경우 클라이언트 옵션에 대한 콜백을 제공합니다`onGetTraceContext`. 이는 애플리케이션이 이미 사용 `@opentelemetry/api` 중이고 범위를 CLI의 범위와 연결하려는 경우에만 필요합니다. SDK는 이 콜백을 `session.create`, `session.resume`, `session.send` RPC 전에 호출합니다.

<!-- 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의 span에 있는 `traceparent` 및 `tracestate`을 모든 언어에서 사용할 수 있습니다.

* **Go**: `ToolInvocation.TraceContext` 필드는 트레이스가 이미 복원된 상태의 `context.Context`이므로, span의 부모로 직접 사용하세요.
* **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] });
```

### 언어별 종속성

| 언어      | 종속성                                  | 비고                                                                                         |
| ------- | ------------------------------------ | ------------------------------------------------------------------------------------------ |
| 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)