Trace GitHub Copilot sessions in VS Code and the Copilot CLI in Arize AX for full observability.GitHub Copilot is GitHub’s AI pair programmer for VS Code and the command line. There are two ways to get Copilot activity into Arize AX: the Arize Coding Harness Tracing, which installs hooks and exports OpenInference spans directly, or Copilot’s own OpenTelemetry export, which Arize AX normalizes on ingestion.
Choose an approach
For a team or an enterprise, prefer the native OpenTelemetry export. It scales without touching every repository, and an administrator can mandate it centrally so developers configure nothing. Use the harness when you need per-category redaction control, or when you want OpenInference spans with no convention mapping in between.
Both paths need an Arize AX Space ID and API key.
Launch Arize AX
To get started, sign up for a free Arize AX account and get your Space ID and API Key:- Log in at app.arize.com
- Click Settings and copy the Space ID
- Open the API Keys tab and create or copy an API key
Install
This installs the Arize Coding Harness. Copilot hooks are installed at the project level under.github/hooks/, so run the installer from the root of each repository where you want tracing.
To avoid a per-repository install entirely, use the native OpenTelemetry export instead, which needs no installer.
Curl installer
macOS / Linux:Local clone
~/.arize/harness/config.json and registers VS Code (.github/hooks/*.json) and Copilot CLI (.github/hooks/hooks.json) hooks in the current project.
The installer runs a short interactive setup. Every harness in the Arize Coding Harness Tracing repo asks the same questions, in the same order.
Setup walkthrough
1. Backend selection
Choose where spans are sent:- Phoenix — your own Phoenix instance.
- Arize AX — the hosted Arize platform.
2. Credentials
The prompts depend on the backend you picked.- Arize AX
- Phoenix
- API key — create one on the API keys tab.
- Space ID — shown on the same settings tab as your API keys.
- OTLP endpoint — defaults to
otlp.arize.com:443. Override it only for a hosted or dedicated instance.
3. Project name
The project that this harness’s spans are grouped under. Defaults to the harness name.4. User ID (optional)
A free-form identifier attached to every span asuser.id. Useful when teammates share one backend. Leave it blank to skip.
5. Content logging
Three[Y/n] opt-outs that apply to every harness, not only the one you are installing:
- Log user prompts?
- Log what tools were asked to do (commands, file paths, URLs)?
- Log what tools returned (file contents, command output)?
logging block in ~/.arize/harness/config.json, which you can edit at any time.
Install flags
Non-interactive install
Pass--non-interactive (or -y) to skip every prompt above and take each value from the environment instead. Nothing is asked, and a missing required value is an error rather than a prompt, which makes this the mode to use from a script, from CI, or when a coding agent is driving the install itself.
Values come from the environment, or from a dotenv file named explicitly with ARIZE_ENV_FILE. Naming a file keeps the API key out of the command line and your shell history.
Content logging is off by default in this mode, unlike the interactive wizard where each question defaults to yes. A
[Y/n] default is a person declining to change an answer they were shown; the same default unattended would capture prompts, commands, and file contents that nobody agreed to. Set the ARIZE_LOG_* variables you want to true.Check what’s installed
status reports which harnesses are configured and whether their hooks are actually wired into each harness’s own settings file. Both have to be true for traces to appear.
hooks: NOT registered means credentials are saved but the harness was never wired up, or something removed the hooks. Re-run the install for that harness.
Use --json from a script or a coding agent to gate on the exit code without parsing output: 0 means every configured harness is wired up, 1 means nothing is configured, and 2 means at least one harness’s hooks are missing. The payload contains no secrets — an API key appears only as "api_key_present": true — so it is safe to paste into a bug report.
Keep it up to date
update pulls the latest code and re-registers every harness already in config.json.
config.json.
Configuration
Credentials live in~/.arize/harness/config.json and apply across all projects. Per-project environment variables override config.json and can be set in your shell profile.
Redaction controls
EachARIZE_LOG_* flag accepts "true" or "false" and defaults to "true". Set to "false" to opt out per category:
Observe
Once tracing is enabled, Copilot activity from both VS Code and the CLI streams to Arize AX. You’ll see:- Turn traces — each prompt → response cycle as a parent span
- Tool spans — nested spans for each tool call with inputs, outputs, and duration
- Subagent spans — activity from any subagents Copilot spawns (VS Code)
- Error spans —
errorOccurredevents from the CLI - Session grouping — all turns from the same session grouped by
session_id
Hooks Captured
Copilot in VS Code and on the CLI use different event names. The Agent Kit handles both with one install command.Native OpenTelemetry export
Copilot Chat emits its own OpenTelemetry traces following the OTel GenAI semantic conventions, with no hooks and no installer. Arize AX normalizesgen_ai.* spans into OpenInference on ingestion, so you can point Copilot straight at the Arize AX OTLP endpoint.
Enabling OTel instruments every agent type at once: the foreground agent, Copilot CLI sessions, Claude agent sessions, and any subagents, with trace context propagated across them.
Set up a single developer
In settings.json:openinference.project.name, spans have no project to land in. OTEL_SERVICE_NAME does not route them.
Leave captureContent off and you get metadata only: model names, token counts, durations, and tool names, but no prompts, responses, or tool arguments.
Roll out across an enterprise
Administrators can mandate the whole configuration through thetelemetry block in Copilot managed settings, delivered by MDM (Intune, Jamf, Group Policy), server-managed settings from your .github-private repository, or a file-based managed-settings.json. Developers configure nothing.
lockCaptureContent prevents developers from changing whether prompt and tool content is captured.
Managed
telemetry.headers are applied only to the Copilot Chat extension’s exporter and are deliberately never passed through environment variables, so an API key cannot leak into the tool subprocesses the agent host spawns. As a consequence, managed headers do not currently reach the agent host, so Copilot CLI terminal sessions still need OTEL_EXPORTER_OTLP_HEADERS set in the environment.Spans Captured
Copilot’s operation names normalize to OpenInference span kinds as follows:
On the agent and chat spans you get prompts and responses as
llm.input_messages and llm.output_messages, token counts, model name, and computed cost. Tool spans carry tool.name, tool.parameters, and the tool result as output.value. gen_ai.conversation.id becomes session.id, so turns group into sessions.
The raw gen_ai.*, github.copilot.*, and copilot_chat.* attributes are all preserved on the span, so you can still filter on things like github.copilot.git.branch.
What does not carry over
- Hook spans are unclassified.
execute_hookis not a recognized GenAI operation, so those spans arrive with no span kind. Theirgithub.copilot.hook.*attributes are preserved and still queryable. - Metrics and events are dropped. Arize AX ingests traces. The
copilot_chat.*metrics (edit acceptance, edit survival, time to first token) and the OTel events are not spans and are not stored. - The provider stays unmapped.
gen_ai.provider.nameisgithub, which is not in the provider table, so it passes through tollm.systemunchanged andllm.provideris left unset.
Reference
For the full list of environment variables, default file paths, and troubleshooting steps, see the Copilot tracing README. For the native export, see Monitor agent usage with OpenTelemetry in the VS Code documentation.Uninstall
Run from the project root where you installed the hooks:github.copilot.chat.otel.enabled to false, or set telemetry.enabled to false in managed settings.