diff --git a/extensions/copilot/docs/monitoring/agent_monitoring.md b/extensions/copilot/docs/monitoring/agent_monitoring.md index 9ccaefef64f..a157960ca83 100644 --- a/extensions/copilot/docs/monitoring/agent_monitoring.md +++ b/extensions/copilot/docs/monitoring/agent_monitoring.md @@ -114,6 +114,18 @@ OTel is **off by default** with zero overhead. It activates when: ## What Gets Exported +> ### Attribute namespaces & dual-emit policy +> +> Copilot Chat emits OTel attributes under three namespaces: +> +> - **`gen_ai.*`** — [OTel GenAI Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/). Use these whenever a standard key exists. +> - **`github.copilot.*`** — The canonical Copilot-specific namespace, shared with the [Copilot CLI runtime](https://github.com/github/copilot-agent-runtime). Prefer this for new dashboards and alerts. +> - **`copilot_chat.*`** — The original VS Code extension namespace. Several keys (notably `copilot_chat.repo.*` and `gen_ai.usage.reasoning_tokens`) are now **dual-emitted alongside the `github.copilot.*` equivalents**. Tables below mark these rows as **Legacy** with a pointer to the preferred key. +> +> Legacy keys continue to emit indefinitely so existing collectors, dashboards, and downstream consumers (Agent Debug Log, Chronicle, SQLite span store) keep working without changes. There is no sunset date. +> +> **Cross-surface compatibility caveat:** A few enums diverge between VS Code and the CLI runtime (e.g. `skill.source` carries VS Code's `PromptFileSource` value on extension-emitted spans and the CLI's own enum on CLI-emitted spans). Where this matters, the divergence is called out on the relevant attribute row. + ### Traces Copilot Chat emits a hierarchical span tree for each agent interaction: @@ -141,6 +153,14 @@ invoke_agent copilot [~15s] | `gen_ai.usage.output_tokens` | Recommended | `3200` | | `gen_ai.usage.cache_read.input_tokens` | When available | `8000` | | `gen_ai.usage.cache_creation.input_tokens` | When available | `4200` | +| `github.copilot.agent.type` | Always | `builtin` \| `custom` \| `plugin` | +| `github.copilot.git.repository` | When in a repo | `https://github.com/microsoft/vscode.git` | +| `github.copilot.git.branch` | When in a repo | `main` | +| `github.copilot.git.commit_sha` | When in a repo | `deadbeef...` | +| `github.copilot.github.org` | GitHub remotes only | `microsoft` | +| `copilot_chat.repo.remote_url` | **Legacy** — prefer `github.copilot.git.repository` | `https://github.com/...` | +| `copilot_chat.repo.head_branch_name` | **Legacy** — prefer `github.copilot.git.branch` | `main` | +| `copilot_chat.repo.head_commit_hash` | **Legacy** — prefer `github.copilot.git.commit_sha` | `deadbeef...` | | `copilot_chat.turn_count` | Always | `4` | | `error.type` | On error | `Error` | | `gen_ai.input.messages` | Opt-in (captureContent) | `[{"role":"user",...}]` | @@ -166,6 +186,8 @@ invoke_agent copilot [~15s] | `gen_ai.usage.output_tokens` | On response | `250` | | `gen_ai.usage.cache_read.input_tokens` | When available | `1200` | | `gen_ai.usage.cache_creation.input_tokens` | When available | `300` | +| `gen_ai.usage.reasoning.output_tokens` | When available | `512` | +| `gen_ai.usage.reasoning_tokens` | **Legacy** — prefer `gen_ai.usage.reasoning.output_tokens` | `512` | | `copilot_chat.time_to_first_token` | On response | `450` | | `server.address` | When available | `api.github.com` | | `copilot_chat.debug_name` | When available | `agentMode` | @@ -182,6 +204,13 @@ invoke_agent copilot [~15s] | `gen_ai.tool.type` | Required | `function` or `extension` (MCP tools) | | `gen_ai.tool.call.id` | Recommended | `call_abc123` | | `gen_ai.tool.description` | When available | `Read the contents of a file` | +| `github.copilot.tool.parameters.edit_type` | Edit tools | `create` \| `update` \| `str_replace` \| `insert` | +| `github.copilot.tool.parameters.skill_name` | When invoking a skill | `auto-perf-optimize` | +| `github.copilot.tool.parameters.mcp_server_name_hash` | MCP tools | SHA-256 hex of server name | +| `github.copilot.tool.parameters.mcp_tool_name` | MCP tools | `search_issues` | +| `github.copilot.tool.parameters.command` | Shell tools, opt-in (captureContent) | `npm test` (truncated to 256 chars) | +| `github.copilot.tool.parameters.file_path` | File tools, opt-in (captureContent) | `/src/app.ts` | +| `github.copilot.tool.parameters.mcp_server_name` | MCP tools, opt-in (captureContent) | `github` | | `error.type` | On error | `FileNotFoundError` | | `gen_ai.tool.call.arguments` | Opt-in (captureContent) | `{"filePath":"/src/index.ts"}` | | `gen_ai.tool.call.result` | Opt-in (captureContent) | `(file contents or summary)` | @@ -628,6 +657,18 @@ copilot-chat invoke_agent claude [~33s] **`execute_hook`** — one span per Claude hook execution (e.g., `Stop` hooks). +| Attribute | Requirement | Example | +|---|---|---| +| `gen_ai.operation.name` | Required | `execute_hook` | +| `copilot_chat.hook_type` | Required | `PreToolUse` | +| `copilot_chat.hook_result_kind` | Always | `success` \| `error` \| `non_blocking_error` | +| `github.copilot.hook.decision` | Always | `pass` \| `block` \| `non_blocking_error` | +| `github.copilot.hook.duration` | Always | `0.142` (seconds) | +| `github.copilot.hook.tool_names` | When tool-scoped | `["bash"]` (JSON array) | +| `copilot_chat.hook_input` | Always | hook input payload (truncated) | +| `copilot_chat.hook_output` | On success | hook stdout (truncated) | +| `error.type` | On error | `Error` | + --- ## Interpreting the Data