Observability for GitHub Copilot with Opik
GitHub Copilot can export traces, metrics and events over OpenTelemetry (OTel) from both the Copilot Chat extension in VS Code and the Copilot CLI. The spans follow the OTel GenAI semantic conventions, which Opik ingests natively, so every chat turn, model call and tool execution lands in Opik as a trace you can review, evaluate and share.
When this guide applies
Section titled “When this guide applies”Use this guide if you want to log Copilot conversations to Opik: the prompts your developers send, the models Copilot calls, the tools it runs, and the tokens each turn consumed.
Quick start
Section titled “Quick start”Copilot Chat in VS Code and Copilot CLI both honor the standard OpenTelemetry environment variables. For a single developer on Opik Cloud, this is the whole setup:
export COPILOT_OTEL_ENABLED=true
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://www.comet.com/opik/api/v1/private/otel
export OTEL_EXPORTER_OTLP_HEADERS='Authorization=<your-api-key>,Comet-Workspace=<your-workspace>,projectName=<your-project-name>'
export COPILOT_OTEL_CAPTURE_CONTENT=true # omit to log structure and tokens only, no prompt textThen launch VS Code from that shell with code . (or run copilot for the CLI) and start a chat.
The trace appears in the Opik project named in projectName. The rest of this page covers the
other configuration paths, self-hosted endpoints, what the spans contain and how to validate.
Prerequisites
Section titled “Prerequisites”- An Opik API key and workspace name. Opik Cloud: comet.com/api/my/settings.
- GitHub Copilot Chat extension in VS Code, or GitHub Copilot CLI, signed in.
- Permission from your organization to export prompt content, if you plan to enable content capture.
What Opik receives
Section titled “What Opik receives”Copilot emits four span kinds, all with gen_ai.* attributes:
| Span | What it represents | Key attributes Opik maps |
|---|---|---|
invoke_agent |
One chat turn (root span) | gen_ai.agent.name, gen_ai.conversation.id |
chat |
A model request | gen_ai.request.model, gen_ai.response.model, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, cache read/creation tokens |
execute_tool |
A tool call | gen_ai.tool.name, gen_ai.tool.type, gen_ai.tool.call.id |
execute_hook |
A hook run | hook metadata |
Opik maps gen_ai.input.messages and gen_ai.output.messages to the trace and span input
and output, and uses gen_ai.usage.* for token counts. gen_ai.conversation.id groups turns
into a thread in the Opik Threads tab.
Opik OTLP endpoint modes
Section titled “Opik OTLP endpoint modes”The examples on this page use the Opik Cloud endpoint. Swap in the endpoint for your deployment
from the tabs here; everything else stays the same. Copilot appends the signal path (/v1/traces,
/v1/metrics, /v1/logs) to the base endpoint itself, so always give it the base URL, not
the /v1/traces URL. For endpoint behavior in general, see the
Opik OpenTelemetry overview.
export OTEL_EXPORTER_OTLP_ENDPOINT=https://www.comet.com/opik/api/v1/private/otel
export OTEL_EXPORTER_OTLP_HEADERS='Authorization=<your-api-key>,Comet-Workspace=<your-workspace>,projectName=<your-project-name>'Required headers:
AuthorizationComet-Workspace
Optional headers:
projectName(recommended; defaults toDefault Project)
export OTEL_EXPORTER_OTLP_ENDPOINT=https://<comet-deployment-url>/opik/api/v1/private/otel
export OTEL_EXPORTER_OTLP_HEADERS='Authorization=<your-api-key>,Comet-Workspace=<your-workspace>,projectName=<your-project-name>'Required headers:
AuthorizationComet-Workspace
Optional headers:
projectName(recommended)
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:5173/api/v1/private/otel
export OTEL_EXPORTER_OTLP_HEADERS='projectName=<your-project-name>'Required headers:
- none by default (depends on your self-hosted auth setup)
Optional headers:
projectName(recommended)- auth headers if your instance enforces auth
Configure Copilot Chat in VS Code
Section titled “Configure Copilot Chat in VS Code”Copilot Chat reads its OTel configuration from VS Code settings, from environment variables, or from enterprise managed settings. Pick the one that matches how you roll out configuration.
The exporter settings live in settings.json, but exporter headers cannot be set in
settings.json. Opik Cloud and Enterprise deployments need the Authorization and
Comet-Workspace headers, so those still come from one environment variable.
- Add to your user or workspace
settings.json:
{
"github.copilot.chat.otel.enabled": true,
"github.copilot.chat.otel.exporterType": "otlp-http",
"github.copilot.chat.otel.otlpEndpoint": "https://www.comet.com/opik/api/v1/private/otel",
"github.copilot.chat.otel.captureContent": true
}- Export the headers in your shell profile:
export OTEL_EXPORTER_OTLP_HEADERS='Authorization=<your-api-key>,Comet-Workspace=<your-workspace>,projectName=<your-project-name>'- Launch VS Code from that shell with
code ., then reload the window.
The same macOS note applies: a Dock or Spotlight launch does not inherit the variable.
Every setting has an environment-variable equivalent. This is the simplest path when VS
Code is launched from a terminal or a wrapper script. Put the block in your shell profile
(~/.zshrc, ~/.bashrc, or the Windows equivalent).
export COPILOT_OTEL_ENABLED=true
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://www.comet.com/opik/api/v1/private/otel
export OTEL_EXPORTER_OTLP_HEADERS='Authorization=<your-api-key>,Comet-Workspace=<your-workspace>,projectName=<your-project-name>'
export COPILOT_OTEL_CAPTURE_CONTENT=true
export OTEL_SERVICE_NAME=copilot-chatStart VS Code from the same shell with code . so the extension host inherits the
variables.
Organizations can mandate where Copilot sends OTel data through the telemetry block
in Copilot managed settings.
Admins deliver it via native MDM (Windows Registry or macOS managed preferences), via a
server-managed policy tied to the signed-in GitHub account, or via a managed-settings.json
file on disk. It applies to both the Copilot Chat extension in VS Code and the agent host
process behind Copilot CLI.
The block lets you set:
- the OTLP endpoint and protocol (
otlp-httpfor Opik) - the OTel service name and resource attributes
- exporter headers, which is where the Opik
Authorization,Comet-WorkspaceandprojectNameheaders go - whether prompt, response and tool content is captured, and whether developers may change that
A managed value always wins over environment variables and user settings, and managed headers are applied only to the Copilot Chat exporter and never passed through environment variables, so the Opik API key never reaches subprocess tools.
Refer to the GitHub changelog linked at the start of this tab for the exact schema of the telemetry
block for your Copilot plan.
Configure Copilot CLI
Section titled “Configure Copilot CLI”Copilot CLI uses the same exporter and the same environment variables as the Quick start. It exports
OTLP over HTTP only (http/protobuf or http/json); gRPC is not supported.
export COPILOT_OTEL_ENABLED=true
export COPILOT_OTEL_EXPORTER_TYPE=otlp-http
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://www.comet.com/opik/api/v1/private/otel
export OTEL_EXPORTER_OTLP_HEADERS='Authorization=<your-api-key>,Comet-Workspace=<your-workspace>,projectName=<your-project-name>'
export COPILOT_OTEL_CAPTURE_CONTENT=true
export OTEL_SERVICE_NAME=copilot-cliRun copilot from that shell and traces are exported as you work.
Validation
Section titled “Validation”- Reload VS Code (or start a new Copilot CLI session) after applying the configuration.
- Ask Copilot something that triggers a tool call, for example "list the files in this repo".
- Open the target project in Opik. You should see an
invoke_agenttrace with nestedchatandexecute_toolspans, token counts on thechatspans, and, with content capture enabled, the prompt and response in the trace input and output. - Open the Threads tab to see the conversation grouped by
gen_ai.conversation.id.
If nothing arrives, set COPILOT_OTEL_LOG_LEVEL=debug and check the GitHub Copilot Chat
output channel in VS Code for exporter errors. A 401 means the Authorization or
Comet-Workspace header did not reach the exporter; the most common cause is VS Code not
inheriting the environment variable.
- Opik ingests the traces signal only. Copilot also sends metrics to
/v1/metricsand events to/v1/logson the same base endpoint; Opik has no receiver for those and rejects them, which is harmless and does not affect trace ingestion. - Keep content capture off unless your policy explicitly allows prompt and response export. Metadata, timing and token counts are still logged without it.
- Cost on
chatspans is calculated fromgen_ai.usage.*when thegen_ai.request.modelorgen_ai.response.modelvalue matches a model in Opik's price table (for examplegpt-4.1). If a span shows no cost, check itsmodelfield and reach out so we can add the alias.