Skip to main content
Skip to content

Copilot SDK 的 OpenTelemetry 检测

本指南演示如何将 OpenTelemetry 跟踪添加到 Copilot SDK 应用程序。

内置遥测支持

SDK 内置支持在 CLI 进程中配置 OpenTelemetry,并在 SDK 和 CLI 之间传播 W3C 跟踪上下文。 创建客户端时提供 TelemetryConfig 以选择启用该功能:

代码语言 navigation

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

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

TelemetryConfig 选项

选项Node.jsPythonGo.NETJavaRust说明
OTLP 终结点otlpEndpointotlp_endpointOTLPEndpointOtlpEndpointotlpEndpointotlp_endpointOTLP HTTP 终结点 URL
OTLP 协议otlpProtocolotlp_protocolOTLPProtocolOtlpProtocolotlpProtocolotlp_protocol所有信号的 OTLP HTTP 协议: "http/json" 或 "http/protobuf"
文件路径filePathfile_pathFilePathFilePathfilePathfile_pathJSON 行跟踪输出的文件路径
导出程序类型exporterTypeexporter_typeExporterTypeExporterTypeexporterTypeexporter_type
"otlp-http" 或 "file"
源名称sourceNamesource_nameSourceNameSourceNamesourceNamesource_name仪器范围名称
捕获内容captureContentcapture_contentCaptureContentCaptureContentcaptureContentcapture_content是否捕获消息内容

OTLP 协议字段用于为所有信号配置 CLI 的 "otlp-http" 导出器。 将其保留为未设置以使用 CLI 默认值,或将其设置为 "http/protobuf" 通过 HTTP 导出 protobuf。

技能与命令遥测

运行时通过优化现有跨度来遵循execute_tool,而不是添加单独的技能操作。 加载程序名为 execute_tool skill {skill}。 明确标识的资源或脚本命名为 execute_tool {tool} {skill} {resource},采用技能相对资源名称。 其他命令文本片段追加实际的已知启动器名称。

  • gen_ai.skill.name 和 gen_ai.skill.resource.name:可独立于内容捕获使用
  • gen_ai.skill.description 和 gen_ai.skill.source.uri:需要通过 TelemetryConfig 进行内容捕获
  • process.executable.name:直接启动的可执行文件,如 shell 启动器,而不是猜测的命令令牌
  • process.executable.path:已知的绝对路径;需要捕获内容
  • process.exit.code:当命令执行工具报告退出时,包括零的整数;省略不可用的退出代码和预启动失败

轮询工具不会从读取的命令继承进程属性。 沙盒后端不提供沙盒可执行文件标识时,将省略这些标识。 非零退出并不意味着工具本身失败。 技能定义和目录列表不称为技能资源。 预加载技能在没有人为构造的工具 span 的情况下生成调用事件。 重复准备相同的选定代理技能上下文会发出一份回执;更改的内容或来源会发出另一份回执。 子会话独立报告自己的预加载。 分离的命令跨度标识直接生成的 Unix sh 监控程序或所选 Windows PowerShell 可执行文件。

覆盖内置名称的自定义工具不会继承原生技能或进程属性。 禁用模型调用时,可见且已启用的技能仍拥有资源。 脚本归因使用挂钩后命令和所选 shell 的目录;当启动脚本或配置文件使执行上下文不确定时,将省略它。

虽然托管遥测设置未解决,但挂起的跟踪缓冲区仅捕获与捕获无关的工具事实。 在策略解析完成前观察到的说明、源 URI 和可执行路径将被省略,即使稍后启用捕获也是如此。 最终策略控制重播;禁用或取消跟踪会丢弃缓冲区。

这些是会导致中断的遥测名称更改:使用 gen_ai.skill.name 而不是 github.copilot.skill.name 或 github.copilot.tool.parameters.skill_name,并使用 gen_ai.skill.source.uri 而不是 github.copilot.skill.path。 本地源值是文件 URI,而不是裸路径。

github.copilot.skill.invoked事件及其内容、源类别、触发器和插件字段仍为 Copilot 特有。 技能内容沿用现有的捕获限制。

技能属性和跨度细化具有开发稳定性;过程属性具有候选发布稳定性。

跟踪上下文传播

大多数用户不需要这样做。 以上 TelemetryConfig 是从 CLI 收集跟踪信息的全部所需。 本节中所述的跟踪上下文传播是一项 高级功能 ,适用于创建自己的 OpenTelemetry 范围的应用程序,并希望它们与 CLI 跨度出现在 相同的分布式跟踪 中。

SDK 可以在 JSON-RPC 有效负载上传播 W3C 跟踪上下文(traceparent/tracestate),以便应用程序范围和 CLI 跨度链接在一个分布式跟踪中。 例如,当你希望在应用中看到“处理工具调用”的 span 嵌套在 CLI 的“执行工具” span 内,或者将 SDK 调用显示为请求处理 span 的子 span 时,这会非常有用。

要沿跟踪进行成本归属,请订阅 assistant.usage 事件并检查 apiEndpoint (AssistantUsageApiEndpoint) 以查看轮次是否使用了 Chat Completions、Responses 或 Anthropic Messages;请参阅 流式处理会话事件。

SDK → CLI(出站)

对于 Node.js,请在 onGetTraceContext 客户端选项中提供回调函数。 仅当应用程序已使用 @opentelemetry/api 并且想要将范围与 CLI 的跨度链接时,才需要这样做。 SDK 在 session.create、session.resume 和 session.send RPC 前调用此回调:

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,可直接将其用作你自定义跨度的父级。
  • Python:通过 trace_context() 在处理程序周围自动回复跟踪上下文,子跨度会自动以 CLI 的跨度作为父级。
  • .NET:通过 RestoreTraceContext() 动恢复追踪上下文,子 Activity 实例会自动以 CLI 的跨度作为父级。
  • Node.js:由于 SDK 没有 OpenTelemetry 依赖,traceparent 和 tracestate 会作为原始字符串通过 ToolInvocation 对象传递。 如果需要,请手动还原上下文:
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 回调函数
Pythonopentelemetry-api利用 pip install copilot-sdk[telemetry] 进行安装
Gogo.opentelemetry.io/otel必需的依赖项
.NET—使用内置 System.Diagnostics.Activity
Javaio.opentelemetry:opentelemetry-api为基于 SDK 的设置添加此依赖项;配置 OpenTelemetry Java 代理或 SDK 时,跟踪上下文注入是自动的

References