Skip to content

[otel-advisor] add gh-aw.event_name span attribute so event type is filterable in all OTel backendsΒ #25846

@github-actions

Description

@github-actions

πŸ“‘ OTel Instrumentation Improvement: add gh-aw.event_name as a span attribute

Analysis Date: 2026-04-11
Priority: Medium
Effort: Small (< 2h)

Problem

github.event_name (the GitHub Actions triggering event β€” issue_comment, pull_request, push, workflow_dispatch, etc.) is added to the resource attributes of every span, but there is no corresponding span attribute carrying the event type.

The existing gh-aw.* span attributes follow a deliberate mirroring pattern:

Resource attribute Span attribute
github.repository gh-aw.repository βœ…
github.run_id gh-aw.run.id βœ…
github.event_name (missing) ❌

The gap means that to filter setup/conclusion spans by event type, an engineer must use backend-specific resource-attribute syntax rather than the consistent gh-aw.* span attribute namespace.

Affected functions (both in actions/setup/js/send_otlp_span.cjs):

  • sendJobSetupSpan β€” reads GITHUB_EVENT_NAME at line 483 but pushes it only to resourceAttributes (line 506), never to attributes
  • sendJobConclusionSpan β€” same pattern: reads eventName at line 679 but pushes it only to resourceAttributes (line 750)

Why This Matters (DevOps Perspective)

Filtering by event type is the most common first step when triaging a spike in failures. The question "are issue_comment-triggered jobs failing more than workflow_dispatch ones?" requires grouping spans by event type.

  • Grafana Tempo: resource attributes require resource.attributes["github.event_name"] syntax, a different filter path from span attributes
  • Sentry: span attributes surface as first-class tags; resource attributes are merged at ingestion and may require different query prefixes
  • Honeycomb: column-based β€” resource attributes that aren't promoted to columns require manual schema setup

With gh-aw.event_name in span attributes, any backend supports a straightforward WHERE gh-aw.event_name = 'issue_comment' filter without special configuration, matching the ergonomics already established by gh-aw.repository and gh-aw.run.id.

MTTR impact: When a new workflow misbehaves only on specific event types, an engineer today must know to look in resource attributes β€” a non-obvious extra step. With this attribute in the span, the event type is immediately visible in any span detail view.

Current Behavior

// Current: actions/setup/js/send_otlp_span.cjs (sendJobSetupSpan, lines 487–514)
const attributes = [
  buildAttr("gh-aw.job.name", jobName),
  buildAttr("gh-aw.workflow.name", workflowName),
  buildAttr("gh-aw.run.id", runId),        // mirrors github.run_id resource attr βœ…
  buildAttr("gh-aw.run.attempt", runAttempt),
  buildAttr("gh-aw.run.actor", actor),
  buildAttr("gh-aw.repository", repository), // mirrors github.repository resource attr βœ…
  // gh-aw.event_name is NOT here ❌
];
// ...
const resourceAttributes = [
  buildAttr("github.repository", repository),
  buildAttr("github.run_id", runId),
  // ...
];
if (eventName) {
  resourceAttributes.push(buildAttr("github.event_name", eventName)); // resource only
}

Proposed Change

// Proposed addition to sendJobSetupSpan (actions/setup/js/send_otlp_span.cjs)
const attributes = [
  buildAttr("gh-aw.job.name", jobName),
  buildAttr("gh-aw.workflow.name", workflowName),
  buildAttr("gh-aw.run.id", runId),
  buildAttr("gh-aw.run.attempt", runAttempt),
  buildAttr("gh-aw.run.actor", actor),
  buildAttr("gh-aw.repository", repository),
];

if (engineId) {
  attributes.push(buildAttr("gh-aw.engine.id", engineId));
}
// ADD THIS:
if (eventName) {
  attributes.push(buildAttr("gh-aw.event_name", eventName));
}

Apply the same addition to sendJobConclusionSpan (around line 714, after the existing conditional gh-aw.job.name push):

// In sendJobConclusionSpan β€” add after the existing attribute pushes
if (eventName) {
  attributes.push(buildAttr("gh-aw.event_name", eventName));
}

Expected Outcome

After this change:

  • In Grafana / Honeycomb / Sentry / Datadog: gh-aw.event_name surfaces as a first-class span attribute, enabling GROUP BY gh-aw.event_name on setup and conclusion spans without special resource-attribute configuration
  • In the JSONL mirror: gh-aw.event_name appears in the spans[0].attributes array of every otel.jsonl entry, making event type immediately readable in artifact-based debugging
  • For on-call engineers: filtering a span search to gh-aw.event_name = issue_comment narrows scope in one click, matching the ergonomics of existing gh-aw.* filters
Implementation Steps
  • In actions/setup/js/send_otlp_span.cjs, inside sendJobSetupSpan (around line 494), add if (eventName) attributes.push(buildAttr("gh-aw.event_name", eventName));
  • In actions/setup/js/send_otlp_span.cjs, inside sendJobConclusionSpan (around line 714), add the same conditional push
  • In actions/setup/js/send_otlp_span.test.cjs, add assertions to the sendJobSetupSpan and sendJobConclusionSpan test suites:
    • Assert span.attributes contains { key: "gh-aw.event_name", value: { stringValue: "workflow_dispatch" } } when GITHUB_EVENT_NAME is set
    • Assert span.attributes does not contain gh-aw.event_name when GITHUB_EVENT_NAME is not set
  • Run cd actions/setup/js && npx vitest run to confirm tests pass
  • Run make fmt to ensure formatting

Evidence from Live Sentry Data

Sentry MCP tools were not available in this analysis environment, so live span payloads could not be sampled. The gap is confirmed by static code analysis:

  • send_otlp_span.cjs line 483: const eventName = process.env.GITHUB_EVENT_NAME || "";
  • send_otlp_span.cjs line 506: resourceAttributes.push(buildAttr("github.event_name", eventName)); β€” resource only
  • send_otlp_span.test.cjs line 1022–1033: existing test confirms github.event_name is in resource attributes β€” no parallel test exists for a span attribute

The design intent of mirroring resource attributes into the gh-aw.* span namespace is already established (gh-aw.repository / github.repository, gh-aw.run.id / github.run_id), making this an obvious completion of the existing pattern.

Related Files

  • actions/setup/js/send_otlp_span.cjs β€” primary change site (both sendJobSetupSpan and sendJobConclusionSpan)
  • actions/setup/js/send_otlp_span.test.cjs β€” add assertions for new span attribute

Generated by the Daily OTel Instrumentation Advisor workflow

Generated by Daily OTel Instrumentation Advisor Β· ● 214.4K Β· β—·

  • expires on Apr 18, 2026, 9:23 PM UTC

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions