{"meta":{"title":"Инструментация OpenTelemetry для Copilot SDK","intro":"В этом руководстве показано, как добавить трассировку OpenTelemetry в ваши приложения Copilot SDK.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ru/enterprise-cloud@latest/copilot","title":"GitHub Copilot"},{"href":"/ru/enterprise-cloud@latest/copilot/how-tos","title":"Инструкции"},{"href":"/ru/enterprise-cloud@latest/copilot/how-tos/copilot-sdk","title":"Второй пилот SDK"},{"href":"/ru/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/observability","title":"Observability"},{"href":"/ru/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/observability/opentelemetry","title":"Открытая телеметрия"}],"documentType":"article"},"body":"# Инструментация OpenTelemetry для Copilot SDK\n\nВ этом руководстве показано, как добавить трассировку OpenTelemetry в ваши приложения Copilot SDK.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n## Встроенная поддержка телеметрии\n\nSDK поддерживает встроенную поддержку настройки OpenTelemetry на процессе CLI и распространения W3C Trace Context между SDK и CLI. Указывайте `TelemetryConfig` при создании клиента для регистрации:\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n<!-- docs-validate: skip -->\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient({\n  telemetry: {\n    otlpEndpoint: \"http://localhost:4318\",\n  },\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n<!-- docs-validate: skip -->\n\n```python\nfrom copilot import CopilotClient\n\nclient = CopilotClient(\n    telemetry={\n        \"otlp_endpoint\": \"http://localhost:4318\",\n    },\n)\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n<!-- docs-validate: skip -->\n\n```golang\nclient := copilot.NewClient(&copilot.ClientOptions{\n    Telemetry: &copilot.TelemetryConfig{\n        OTLPEndpoint: \"http://localhost:4318\",\n    },\n})\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n<!-- docs-validate: skip -->\n\n```csharp\nvar client = new CopilotClient(new CopilotClientOptions\n{\n    Telemetry = new TelemetryConfig\n    {\n        OtlpEndpoint = \"http://localhost:4318\",\n    },\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nimport com.github.copilot.CopilotClient;\nimport com.github.copilot.rpc.*;\n\nvar client = new CopilotClient(new CopilotClientOptions()\n    .setTelemetry(new TelemetryConfig()\n        .setOtlpEndpoint(\"http://localhost:4318\"))\n);\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n<!-- docs-validate: skip -->\n\n```rust\nuse github_copilot_sdk::{Client, ClientOptions, TelemetryConfig};\n\nlet client = Client::start(ClientOptions::new()\n    .with_telemetry(TelemetryConfig::new()\n        .with_otlp_endpoint(\"http://localhost:4318\"))\n).await?;\n```\n\n</div>\n\n</div>\n\n### Опции TelemetryConfig\n\n| Опция                      | Node.js          | Python            | Go               | .NET             | Java             | Rust              | Описание                                                                  |\n| -------------------------- | ---------------- | ----------------- | ---------------- | ---------------- | ---------------- | ----------------- | ------------------------------------------------------------------------- |\n| Конечная точка OTLP        | `otlpEndpoint`   | `otlp_endpoint`   | `OTLPEndpoint`   | `OtlpEndpoint`   | `otlpEndpoint`   | `otlp_endpoint`   | URL конечной точки OTLP HTTP                                              |\n| Протокол OTLP              | `otlpProtocol`   | `otlp_protocol`   | `OTLPProtocol`   | `OtlpProtocol`   | `otlpProtocol`   | `otlp_protocol`   | Протокол OTLP HTTP для всех сигналов: `\"http/json\"` или `\"http/protobuf\"` |\n| Путь к файлу               | `filePath`       | `file_path`       | `FilePath`       | `FilePath`       | `filePath`       | `file_path`       | Путь файла для вывода JSON-lines trace                                    |\n| Тип экспортера             | `exporterType`   | `exporter_type`   | `ExporterType`   | `ExporterType`   | `exporterType`   | `exporter_type`   |                                                                           |\n| `\"otlp-http\"` или `\"file\"` |                  |                   |                  |                  |                  |                   |                                                                           |\n| Имя источника              | `sourceName`     | `source_name`     | `SourceName`     | `SourceName`     | `sourceName`     | `source_name`     | Название области приборов                                                 |\n| Захват контента            | `captureContent` | `capture_content` | `CaptureContent` | `CaptureContent` | `captureContent` | `capture_content` | Нужно ли фиксировать содержимое сообщений                                 |\n\nПоле протокола OTLP настраивает `\"otlp-http\"` экспортера CLI для всех сигналов. Оставьте его неустановленным, чтобы использовать CLI по умолчанию, или поставьте на `\"http/protobuf\"` экспорт protobuf через HTTP.\n\n### Распространение контекста следов\n\n> **Большинству пользователей это не нужно.** Вышеописанное — всё, `TelemetryConfig` что нужно для сбора трассировок из CLI. Распространение контекста трассировки, описанное в этом разделе, является **продвинутой функцией** для приложений, которые создают собственные OpenTelemetry spans и хотят, чтобы они отображались **в той же распределённой трассе** , что и spans CLI.\n\nSDK может передавать W3C Trace Context (`traceparent`/`tracestate`) на JSON-RPC полезных нагрузках, чтобы span-и вашего приложения и CLI были связаны в одну распределённую трассу. Это полезно, когда, например, вы хотите увидеть span «handle tool call» в вашем приложении, встроенный в span «execute tool» CLI, или показывать SDK-вызов как дочерний span обработки запросов.\n\nДля атрибуции стоимости вместе с трассами подписывайтесь на события `assistant.usage` и проверяйте `apiEndpoint` (`AssistantUsageApiEndpoint`), чтобы узнать, использовал ли ход завершения чата, ответы или Anthropic сообщения; см. [События потоковых сессий](/ru/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/streaming-events).\n\n#### SDK → CLI (исходящий маршрут)\n\nДля **Node.js**дайте обратный `onGetTraceContext` звонок по вариантам клиента. Это необходимо только если ваше приложение уже использует `@opentelemetry/api` это и вы хотите связать свои соны с спанами CLI. SDK вызывает этот обратный вызов перед `session.create`, `session.resume`, и `session.send` RPC:\n\n<!-- docs-validate: skip -->\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\nimport { propagation, context } from \"@opentelemetry/api\";\n\nconst client = new CopilotClient({\n  telemetry: { otlpEndpoint: \"http://localhost:4318\" },\n  onGetTraceContext: () => {\n    const carrier: Record<string, string> = {};\n    propagation.inject(context.active(), carrier);\n    return carrier; // { traceparent: \"00-...\", tracestate: \"...\" }\n  },\n});\n```\n\nДля **Python**, **Go** и **.NET** инъекция контекста trace происходит автоматически при настройке соответствующего API OpenTelemetry/Activity — обратный вызов не требуется.\n\n#### CLI → SDK (входящий)\n\nКогда CLI вызывает обработчик инструментов, `traceparent` диапазон и `tracestate` из CLI доступны во всех языках:\n\n* **Вперед**: поле `ToolInvocation.TraceContext` уже `context.Context` восстановлено с трассировкой — используйте его напрямую как родителя для ваших пролётов.\n* **Python**: Контекст трассировки автоматически восстанавливается вокруг обработчика через `trace_context()` — дочерние спыны автоматически прикрепляются к спану CLI.\n* **.NET**: Трассирующий контекст автоматически восстанавливается через `RestoreTraceContext()` — дочерние экземпляры `Activity` автоматически связываются с span CLI.\n* **Node.js**: Поскольку SDK не зависит `traceparent` от OpenTelemetry и `tracestate` передаются в виде сырых строк на объекте `ToolInvocation` . При необходимости восстанавливайте контекст вручную:\n\n<!-- docs-validate: skip -->\n\n```typescript\nimport { defineTool } from \"@github/copilot-sdk\";\nimport { propagation, context, trace } from \"@opentelemetry/api\";\n\nconst myTool = defineTool(\"my-tool\", {\n  description: \"Do work\",\n  handler: async (args, invocation) => {\n    // Restore the CLI's trace context as the active context\n    const carrier = {\n      traceparent: invocation.traceparent,\n      tracestate: invocation.tracestate,\n    };\n    const parentCtx = propagation.extract(context.active(), carrier);\n\n    // Create a child span under the CLI's span\n    const tracer = trace.getTracer(\"my-app\");\n    return context.with(parentCtx, () =>\n      tracer.startActiveSpan(\"my-tool\", async (span) => {\n        try {\n          const result = await doWork(args);\n          return result;\n        } finally {\n          span.end();\n        }\n      })\n    );\n  },\n});\n\n// Tool handlers are registered when the session is created.\nconst session = await client.createSession({ tools: [myTool] });\n```\n\n### Зависимости по языкам\n\n| Язык    | Зависимость                          | Notes                                                                                                                                                   |\n| ------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Node.js | —                                    | Никакой зависимости; обеспечить `onGetTraceContext` обратный вызов для исходящего распространения                                                       |\n| Python  | `opentelemetry-api`                  | Установка с помощью `pip install copilot-sdk[telemetry]`                                                                                                |\n| Go      | `go.opentelemetry.io/otel`           | Требуемая зависимость                                                                                                                                   |\n| .NET    | —                                    | Использование встроенных систем `System.Diagnostics.Activity`                                                                                           |\n| Java    | `io.opentelemetry:opentelemetry-api` | Добавьте эту зависимость для настройки на основе SDK; инъекция контекста trace происходит автоматически при настройке агента OpenTelemetry Java или SDK |\n\n## Ссылки\n\n* [Семантические конвенции OpenTelemetry GenAI](https://opentelemetry.io/docs/specs/semconv/gen-ai/)\n* [Семантические конвенции MCP OpenTelemetry](https://opentelemetry.io/docs/specs/semconv/gen-ai/mcp/)\n* [Пакет SDK Python OpenTelemetry](https://opentelemetry.io/docs/instrumentation/python/)\n* [Copilot документация SDK](https://github.com/github/copilot-sdk)"}