Skip to content

Configure agent OTEL file export and forward Copilot traces to OTLP#30530

Merged
pelikhan merged 5 commits intomainfrom
copilot/configure-copilot-agent-otel
May 6, 2026
Merged

Configure agent OTEL file export and forward Copilot traces to OTLP#30530
pelikhan merged 5 commits intomainfrom
copilot/configure-copilot-agent-otel

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 6, 2026

Summary

  • inject COPILOT_OTEL_FILE_EXPORTER_PATH into workflow env whenever OTLP is configured
  • add Copilot telemetry JSONL forwarding logic that parses line-delimited payloads and forwards valid OTLP traces to configured OTLP endpoints
  • mirror sanitized forwarded payloads into /tmp/gh-aw/otel.jsonl
  • include raw Copilot telemetry JSONL (/tmp/gh-aw/copilot-otel.jsonl) in unified agent artifact uploads
  • update OTLP injection tests to validate the new environment variable

Validation

  • make build && make fmt
  • go test -v -run "TestInjectOTLPConfig|TestInjectOTLPConfig_MultipleEndpoints" ./pkg/workflow/
  • make lint-cjs
  • make agent-report-progress
  • secret_scanning on changed files
  • parallel_validation (Code Review + CodeQL)

Changeset

  • Type: patch
  • Description: Forward Copilot telemetry JSONL traces to configured OTLP endpoints and include the raw telemetry file in unified agent artifacts.

Generated by Changeset Generator for issue #30530 ·



✨ PR Review Safe Output Test - Run 25432044951

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 208.6K ·

Copilot AI and others added 2 commits May 6, 2026 05:46
Copilot AI requested a review from pelikhan May 6, 2026 05:53
@pelikhan pelikhan marked this pull request as ready for review May 6, 2026 05:56
Copilot AI review requested due to automatic review settings May 6, 2026 05:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends existing OTLP observability support by configuring Copilot CLI’s OTEL file-exporter output path when OTLP is enabled, and adds runtime logic to forward Copilot’s line-delimited OTLP trace payloads to the configured OTLP endpoints while mirroring sanitized payloads to the existing /tmp/gh-aw/otel.jsonl mirror and uploading the raw Copilot JSONL as an artifact.

Changes:

  • Inject COPILOT_OTEL_FILE_EXPORTER_PATH into the workflow env: block whenever OTLP is configured.
  • Add a new export_copilot_otel_traces.cjs module and call it from the observability summary step to parse Copilot JSONL and forward valid OTLP payloads to all configured endpoints.
  • Include /tmp/gh-aw/copilot-otel.jsonl in unified agent artifact uploads (when OTLP is enabled) and add the associated constant + injection tests.
Show a summary per file
File Description
pkg/workflow/observability_otlp.go Injects COPILOT_OTEL_FILE_EXPORTER_PATH into generated workflow env when OTLP is enabled.
pkg/workflow/observability_otlp_test.go Updates OTLP injection tests to assert the new env var is present.
pkg/workflow/compiler_yaml_main_job.go Adds Copilot OTEL JSONL file to agent artifact paths when OTLP is enabled.
pkg/constants/job_constants.go Introduces CopilotOtelJsonlFilename constant for /tmp/gh-aw/copilot-otel.jsonl.
actions/setup/js/generate_observability_summary.cjs Calls the new Copilot OTEL export/forwarding routine before building the summary.
actions/setup/js/export_copilot_otel_traces.cjs New JSONL parsing + forwarding implementation (sanitize + mirror to otel.jsonl; forward to OTLP endpoints).

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 6/6 changed files
  • Comments generated: 3

Comment on lines +43 to +67

const stream = fs.createReadStream(sourcePath, { encoding: "utf8" });
const lines = readline.createInterface({ input: stream, crlfDelay: Infinity });
for await (const raw of lines) {
const line = raw.trim();
if (!line) continue;

let payload;
try {
payload = JSON.parse(line);
} catch {
malformed++;
continue;
}

if (!isOTLPPayload(payload)) {
ignored++;
continue;
}

const sanitized = sanitizeOTLPPayload(payload);
appendToOTLPJSONL(sanitized);

await sendOTLPToAllEndpoints(endpoints, payload, { skipJSONL: true });
forwarded++;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 Smoke test agent here, confirming this PR review comment was found and replied to! The smoke test is passing smoothly. 🎉

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 14.7M

Comment on lines +22 to +71
async function main(core) {
const sourcePath = process.env.COPILOT_OTEL_FILE_EXPORTER_PATH || "";
if (!sourcePath) {
core.info("COPILOT_OTEL_FILE_EXPORTER_PATH is not set; skipping Copilot OTEL trace export");
return;
}

if (!fs.existsSync(sourcePath)) {
core.info(`Copilot OTEL trace file not found at ${sourcePath}; skipping export`);
return;
}

const endpoints = parseOTLPEndpoints();
if (endpoints.length === 0) {
core.info("GH_AW_OTLP_ENDPOINTS is not configured; skipping Copilot OTEL endpoint export");
return;
}

let forwarded = 0;
let malformed = 0;
let ignored = 0;

const stream = fs.createReadStream(sourcePath, { encoding: "utf8" });
const lines = readline.createInterface({ input: stream, crlfDelay: Infinity });
for await (const raw of lines) {
const line = raw.trim();
if (!line) continue;

let payload;
try {
payload = JSON.parse(line);
} catch {
malformed++;
continue;
}

if (!isOTLPPayload(payload)) {
ignored++;
continue;
}

const sanitized = sanitizeOTLPPayload(payload);
appendToOTLPJSONL(sanitized);

await sendOTLPToAllEndpoints(endpoints, payload, { skipJSONL: true });
forwarded++;
}

core.info(`Copilot OTEL trace export complete: forwarded=${forwarded}, malformed=${malformed}, ignored=${ignored}, source=${sourcePath}`);
}
}

async function main(core) {
await exportCopilotOtelTraces(core);
@github-actions github-actions Bot mentioned this pull request May 6, 2026
@pelikhan pelikhan added the smoke label May 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🚀 Smoke Pi MISSION COMPLETE! Pi delivered. 🥧

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

⚠️ Smoke Gemini failed. Gemini encountered unexpected challenges...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

Smoke test 25432044951 complete — all 18 non-skipped tests passed (test #19 skipped, no safe PR to close). Issue created, PR #30530 reviewed and updated, label smoke-claude added, discussion #30574 commented, Slack message posted, code scanning alert created, smoke test file pushed to PR branch.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions github-actions Bot removed the smoke label May 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Agent Container Tool Check

Tool Status Version
bash 5.2.21
sh available
git 2.53.0
jq 1.7
yq 4.52.5
curl 8.5.0
gh 2.89.0
node 22.22.2
python3 3.10.16 (PyPy 7.3.19)
go 1.24.13
java 10.0.201
dotnet NOT FOUND

Result: 11/12 tools available ⚠️ FAIL — dotnet is missing

🔧 Tool validation by Agent Container Smoke Test · ● 1.2M ·

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🧪 Test Quality Sentinel Report

Test Quality Score: 65/100

⚠️ Acceptable, with suggestions

Metric Value
New/modified test cases analyzed 2
✅ Design tests (behavioral contracts) 2 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 0 (0%)
Duplicate test clusters 1
Test inflation detected No (2:2 ratio)
🚨 Coding-guideline violations 1 (missing assertion message)

Test Classification Details

Test Case File Classification Issues Detected
TestInjectOTLPConfig / secrets-based endpoint pkg/workflow/observability_otlp_test.go:196 ✅ Design Assertion message provided ✅
TestInjectOTLPConfig / adds domain to new NetworkPermissions and injects env vars for static URL pkg/workflow/observability_otlp_test.go:216 ✅ Design ⚠️ Missing assertion message

Flagged Items — Requires Review

⚠️ Missing assertion message at observability_otlp_test.go:216

Issue: The assert.Contains call at line 216 lacks a descriptive message argument, violating the project guideline that every assertion should include context for readers.

// ❌ Current (no message)
assert.Contains(t, wd.Env, "COPILOT_OTEL_FILE_EXPORTER_PATH: /tmp/gh-aw/copilot-otel.jsonl")

// ✅ Suggested fix
assert.Contains(t, wd.Env, "COPILOT_OTEL_FILE_EXPORTER_PATH: /tmp/gh-aw/copilot-otel.jsonl", "should configure Copilot OTEL file exporter path")

⚠️ No error/edge case coverage added

Both new assertions cover the happy path only. Consider adding a subtest for the case where OTLP_ENDPOINT is absent or empty to verify that COPILOT_OTEL_FILE_EXPORTER_PATH is still (or not) injected in that scenario.


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 2 assertion additions across 2 existing subtests (unit, //go:build !integration ✅)
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 tests

Verdict

Check passed. 0% of modified test cases are implementation tests (threshold: 30%). The noted missing assertion message is a minor style violation; the test changes correctly validate the new COPILOT_OTEL_FILE_EXPORTER_PATH environment variable injection as a behavioral contract.

📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.


References: §25418992811

🧪 Test quality analysis by Test Quality Sentinel · ● 5.9M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 65/100. Test quality is acceptable — 0% of modified test cases are implementation tests (threshold: 30%). Minor: one assertion is missing a descriptive message at observability_otlp_test.go:216.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Commit pushed: 3594a90

Generated by Changeset Generator

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Codex smoke: FAIL
PRs: #30525 Add homepage JSON-LD graph for WebSite, SoftwareApplication, Organization, FAQ, and SearchAction; #30536 refactor: extract getRunFailureStatusText helper to eliminate duplicated status mapping in notify_comment_error
✅ GitHub MCP, Serena, Playwright, file write, bash, build, comment memory, cache memory
❌ Web Fetch MCP unavailable
Run: https://github.com/github/gh-aw/actions/runs/25432044897

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex ·

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Comment Memory

Smoke checks settle
GitHub title in the glass
May logs hold the mark

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex ·

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🤖 Beep boop! The smoke test agent was here! 👋 Just popping in to say all systems are GO and tests are passing. Nothing to see here... unless you like watching robots flex their circuits. 💪✨

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 14.7M ·

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🎉 The smoke test has spoken! Every test gleamed like a freshly-deployed microservice. I ran, I tested, I conquered! 🤖 From Playwright to Serena, from haiku dispatch to artifact upload — all systems nominal. The binary lives, the builds compile, and the robots are happy. May your pipelines always be green! 🌟

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 14.7M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smoke test review: PR adds Copilot OTEL trace forwarding. Code is clean and follows existing patterns. Inline comments note minor improvement opportunities.

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 14.7M

*/
async function main(core) {
const sourcePath = process.env.COPILOT_OTEL_FILE_EXPORTER_PATH || "";
if (!sourcePath) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

�� Consider adding a check for endpoints.length === 0 before creating the file read stream. Currently, the stream is created before the endpoints check, which wastes resources if no OTLP endpoints are configured.

const OtelJsonlFilename = "otel.jsonl"

// CopilotOtelJsonlFilename is the filename of the Copilot CLI OpenTelemetry
// file-exporter output written to /tmp/gh-aw/.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Good constant naming! CopilotOtelJsonlFilename follows existing naming conventions. Worth adding a note in the comment about the env var COPILOT_OTEL_FILE_EXPORTER_PATH that references this path, so reviewers can trace the full flow.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

💥 Smoke Test 25432044951 — Claude Engine

Core (#1-12): ✅✅✅✅✅✅✅✅✅✅✅✅
PR Review (#13-19): ✅✅✅✅✅✅⚠️(#19 skipped)

Overall: PASS

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 208.6K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💥 Automated smoke test review - all systems nominal! [Run 25432044951]

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 208.6K

* @param {import("@actions/core")} core
* @returns {Promise<void>}
*/
async function main(core) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smoke test review comment #1 — The main function cleanly handles the early-exit cases (missing env var, missing file, no endpoints). Good defensive programming pattern. [Run 25432044951]

@@ -382,6 +383,7 @@ func (c *Compiler) injectOTLPConfig(workflowData *WorkflowData) {
// OTEL_EXPORTER_OTLP_ENDPOINT and OTEL_SERVICE_NAME are set to the first
// endpoint for backward compatibility (MCP gateway, legacy scripts).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smoke test review comment #2COPILOT_OTEL_FILE_EXPORTER_PATH is correctly injected alongside existing OTEL env vars. The constant reference keeps naming consistent across the codebase. [Run 25432044951]

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented May 6, 2026

@copilot merge main and recompile

Copilot AI and others added 2 commits May 6, 2026 11:41
…ilot-agent-otel

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 6, 2026

@copilot merge main and recompile

Done — merged origin/main and recompiled workflows. Commits: d9918bd (merge) and 65a7a10 (recompile lock files).

@pelikhan pelikhan merged commit 6bd6baa into main May 6, 2026
@pelikhan pelikhan deleted the copilot/configure-copilot-agent-otel branch May 6, 2026 11:47
Copilot stopped work on behalf of pelikhan due to an error May 6, 2026 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants