如何为 VS Code Agent Host 启用 OTel 追踪并将 trace 导出到 OTLP 采集端点
【免费下载链接】vscodeVisual Studio Code项目地址: https://gitcode.com/GitHub_Trending/vscode6/vscode
VS Code 的Agent Host是一个独立的 utility 进程(位于src/vs/platform/agentHost/),用于承载 native 的 Copilot、Claude 和 Codex 运行时,而不是走扩展宿主内的 in-process harness。当你需要把这些 agent 会话产生的 OpenTelemetry(OTel)trace 发送到自己的 OTLP 采集端点(如 Aspire Dashboard、Jaeger 或其他 OTLP 兼容 collector)时,需要配置chat.agentHost.otel.*这一组设置。该能力目前仅在Insiders / 非 stable 构建中可用。
注意它与扩展侧的 OTel 管线(github.copilot.chat.otel.*,文档见 agent_monitoring.md)是两套独立管线:前者在扩展宿主中运行,设置前缀和持久化位置都不同。
准备条件
- VS Code 构建:Insiders 或其他非 stable 构建(文档明确标注 Availability 为 Insiders / non-stable builds only)。
- 一个可访问的 OTLP 兼容 collector。示例主路径使用 Aspire Dashboard:它是一个带内置 OTLP/HTTP 端点和 Web 界面的容器镜像,无需云账号。前提是你已安装 Docker。
启动 Aspire Dashboard(来自 agent_monitoring.md 的 Quick Start 命令)。该命令会拉取镜像并以后台方式启动一个名为aspire-dashboard的容器:
docker run --rm -d \ -p 18888:18888 \ -p 4318:18890 \ --name aspire-dashboard \ mcr.microsoft.com/dotnet/aspire-dashboard:latest端口映射的含义:18888是 dashboard 的 Web 界面端口,4318是 OTLP/HTTP 接收端口(即 trace 要发送的端点)。
选择工作模式:pass-through 还是 DB 模式
Agent Host OTel 有两种模式,配置前先确定你要哪一种:
| 模式 | 触发条件 | 行为 |
|---|---|---|
| Pass-through | chat.agentHost.otel.enabled为true且dbSpanExporter.enabled为false | SDK 直接导出到你配置的 exporter(OTLP/HTTP、OTLP/gRPC、file 或 console),span 不被拦截 |
| DB 模式 | chat.agentHost.otel.dbSpanExporter.enabled为true(隐式启用 OTel) | SDK 指向 Agent Host 内127.0.0.1上的 loopback OTLP/HTTP receiver,span 解码后写入本地 SQLite 数据库;若外部端点为 OTLP/HTTP JSON,还会把规范化后的 JSON body 转发到你的 collector |
两者也可以同时开:文档给出的 Quick Start 组合就同时启用 DB 落盘和 OTLP 转发,既能在 dashboard 里看实时会话,又能事后查询原始数据。
配置设置
打开Settings(Ctrl+,),搜索agentHost otel,或直接编辑settings.json。主路径(pass-through 导出到 OTLP 端点):
{ "chat.agentHost.otel.enabled": true, "chat.agentHost.otel.otlpEndpoint": "http://localhost:4318" }otlpEndpoint支持两种写法(与标准OTEL_EXPORTER_OTLP_ENDPOINT约定一致):
- 裸 base URL(如
http://localhost:4318):需要时自动追加/v1/traces; - 完整信号级 URL(如
http://host:4318/v1/traces):原样使用。
如果同时想本地落盘,再加上 DB 开关(文档 Quick Start 的完整示例):
{ "chat.agentHost.otel.enabled": true, "chat.agentHost.otel.captureContent": true, "chat.agentHost.otel.dbSpanExporter.enabled": true, "chat.agentHost.otel.otlpEndpoint": "http://localhost:4318" }其余相关设置的默认值与用途(来自 OTEL.md):
| 设置 | 默认值 | 说明 |
|---|---|---|
chat.agentHost.otel.exporterType | "otlp-http" | 可选otlp-http、otlp-grpc、console、file。CLI runtime 会透明地把otlp-grpc降级为otlp-http |
chat.agentHost.otel.captureContent | false | 在 span 属性中捕获 prompt/response 内容。隐私敏感,文档明确警告:不要把 span 发往共享 sink 的环境中开启 |
chat.agentHost.otel.outfile | "" | exporterType为file时的 JSON-lines 输出路径 |
chat.agentHost.otel.dbSpanExporter.enabled | false | 把每个 span 持久化到<userData>/agent-host/otel/agent-host-traces.db,隐式启用 OTel |
这些设置只可在用户级 settings 中配置,并且最终会被翻译成 Agent Host 进程的环境变量,对应关系(翻译点在 agentService.ts 的buildAgentHostOTelEnv(),设置注册在 agentHostStarter.config.contribution.ts):
| 设置 | 环境变量 |
|---|---|
chat.agentHost.otel.enabled | COPILOT_OTEL_ENABLED |
chat.agentHost.otel.exporterType | COPILOT_OTEL_EXPORTER_TYPE |
chat.agentHost.otel.otlpEndpoint | OTEL_EXPORTER_OTLP_ENDPOINT(COPILOT_OTEL_ENDPOINT也接受且优先) |
chat.agentHost.otel.captureContent | OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT |
chat.agentHost.otel.outfile | COPILOT_OTEL_FILE_EXPORTER_PATH |
chat.agentHost.otel.dbSpanExporter.enabled | COPILOT_OTEL_DB_SPAN_EXPORTER_ENABLED |
优先级:企业 managed policy(策略) > 父进程环境变量 > 用户设置。如果你在父进程环境里已经设置了同名变量(开发覆盖),它会赢过对应设置;而企业策略值则赢过父进程环境变量。
让配置生效:必须重启
环境变量在 Agent Hostspawn 时绑定,IAgentHostOTelService在构造时读取一次process.env并缓存。会话中途修改chat.agentHost.otel.*设置对已在运行的 Agent Host没有任何效果——改完设置后必须 reload window 或重启 VS Code。
重启后,在 Copilot Chat 中发起一次 agent 会话(例如 Agent 模式下发一条消息)来产生 span。
结果验证
Pass-through 路径:在 collector 端查看
用 Aspire Dashboard 作 collector 时,打开http://localhost:18888进入Traces页面即可看到会话 trace(dashboard UI 端口来自上面的 docker 映射)。Agent Host 会把所有 provider 的 trace 归到一个 trace id 下:宿主发出零时长的vscode.agent_host.sessionanchor span,并把 W3Ctraceparent/tracestate传给各 native runtime,因此 Copilot、Claude、Codex 的原生 trace 共享同一个 trace id。各 producer 的service.name分别为github-copilot、claude-code、codex-app-server,宿主侧元数据 span 为vscode-agent-host,共同带上service.namespace=vscode.agent-host资源属性,可以用这些属性在 collector 中过滤。
DB 模式:本地 SQLite 验证与导出
启用chat.agentHost.otel.dbSpanExporter.enabled后,所有 span 写入:
<userData>/agent-host/otel/agent-host-traces.db用命令Chat: Export Agent Host Traces Database…(命令 idworkbench.action.chat.agentHost.otel.exportAgentTracesDB)把数据库复制一份用于离线检查。该命令仅在 DB 开关为true时出现(实现见 exportAgentTracesDb.ts)。几个可用于判断结果的行为:
- 数据库还不存在时,命令会提示
No agent host trace database found yet. Run an agent session with chat.agentHost.otel.dbSpanExporter.enabled turned on to populate it.——说明还没有在 DB 模式下跑过 agent 会话; - 存储使用 WAL 模式,运行中也可以安全地复制文件或用
sqlite3查询; - 导出时若存在
-wal/-shm边车文件,会一并复制,得到的三件套是可直接打开并 checkpoint 的合法 WAL 数据库。
排查与限制
- 改了设置没有 trace:先确认已 reload window / 重启 VS Code(spawn-time 绑定);再确认父进程环境没有同名变量把设置顶掉。
- DB 模式 + 外部端点的协议限制:loopback 一跳固定使用 OTLP/HTTP JSON;外部端点为 OTLP/HTTP JSON 时 span 会被转发,但外部协议为 protobuf 或 gRPC 时,trace 只留在本地 SQLite(provider 的 logs/metrics 仍直接导出)。
- 认证头:
OTEL_EXPORTER_OTLP_HEADERS(如Authorization=Bearer …)只能通过环境变量继承传递给 Agent Host;企业 managed headers 只作用于 Copilot Chat 扩展的 exporter,不会投递给 Agent Host(避免密钥泄漏到工具子进程),向 provider 子进程投递 managed header 目前也不支持。 - Codex 0.142 临时过滤:DB 模式下 loopback receiver 会丢弃 Codex 的认证轮询 span(资源
service.name=codex-app-server、span 名auth、code.module.name=codex_login::auth::manager三者同时满足),该 span 约每秒两次;其他 Codex span 不受影响。 - 标题元数据 span:
vscode.agent_host.session.title_changedspan 只在captureContent开启时发出,重复设置相同标题不会重复发。
备选:用仓库内置的 collector 栈
extensions/copilot/docs/monitoring/ 目录还提供了一个 docker compose 栈(docker-compose.yaml + otel-collector-config.yaml):OTel Collector 在宿主机4328(HTTP)和4327(gRPC)接收 OTLP,转发到 Azure Application Insights、本地 Jaeger(UI 在http://localhost:16687)以及 stdout debug 导出器。它是任意 OTLP 兼容 collector 的另一个可选实例,需要按文件头部说明设置APPLICATIONINSIGHTS_CONNECTION_STRING;Agent Host 侧只需把chat.agentHost.otel.otlpEndpoint指向http://localhost:4328。
用完 Aspire Dashboard 后,用docker stop aspire-dashboard停止容器收尾。更完整的管线行为、资源属性与信号路由细节见 OTEL.md,实现入口是 agentHostOTelService.ts。
【免费下载链接】vscodeVisual Studio Code项目地址: https://gitcode.com/GitHub_Trending/vscode6/vscode
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考