# How to Get Organization-Wide Visibility Into GitHub Actions CI Health Without Touching a Single Workflow File
**Posted on September 8, 2026**
—
## The Problem No One Wants to Own
GitHub Actions usage quietly scales across organizations while actual observability doesn’t keep pace. Which workflows are slow? Which ones are flaky? How long do jobs sit queued for a runner before they even begin executing? GitHub’s built-in insights are per-repository and shallow — there’s no cross-organization view of CI health, no way to slice by team or workflow type, and no way to alert when things deteriorate without anyone noticing. The inevitable result is someone asking why a build took forty minutes yesterday, and the honest answer is “let me go check that one repo and get back to you.”
The good news is that this is solvable without asking a single team to modify a single workflow file.
—
## Why the Obvious Fix Doesn’t Scale
The instinctive answer is to instrument each workflow individually — add a tracing step, wire up an SDK, sprinkle spans through every YAML file. Technically, it works. But it means every team has to opt in, every new repository starts blind until someone remembers to add it, and you end up maintaining instrumentation scattered across however many workflow files exist across the organization. That approach doesn’t scale with your organization; it scales with how diligent everyone stays about something that isn’t their actual job.
—
## The Real Source of Truth
GitHub already knows almost everything you need. Every workflow run and every job inside it emits events — specifically `workflow_run` and `workflow_job`. You don’t need to ask each repository to report on itself. You just need to listen to what GitHub is already broadcasting, at the organization level, from a single point.
Think of it this way: trying to track an entire apartment building’s water usage by asking every tenant to self-report their reading is a recipe for gaps. Most will forget. New tenants won’t even know they’re supposed to. The easier answer is to read the one meter at the street, where every pipe in the building already converges — whether the tenants are aware of it or not.
—
## How the Implementation Actually Works
An OpenTelemetry Collector configured with the `githubreceiver` component sits behind a single organization-level GitHub webhook and converts incoming `workflow_run` and `workflow_job` events directly into OTLP spans. The data model maps intuitively: a workflow becomes one outer span, each job inside it becomes a child span, and each step within a job becomes a child of that job span. The result is something you can drill into deeply rather than a flat, unmanageable pile of events.
One practical detail worth noting: span and trace IDs are generated deterministically, hashed from the workflow’s run ID and each job’s check run ID. If you ever want to emit your own telemetry from inside a specific step, there’s tooling available to compute the matching ID and attach it directly to the same trace without coordinating with the collector.
A minimal configuration looks like this:
“`yaml
receivers:
github:
webhook:
endpoint: 0.0.0.0:19418
path: /events
secret: ${env:GITHUB_WEBHOOK_SECRET}
scrapers: # required even if you only want tracing — a dummy entry suffices
scraper:
github_org: ${env:GITHUB_ORG}
exporters:
otlp:
endpoint: ${env:TRACE_BACKEND_ENDPOINT}
headers:
authorization: ${env:TRACE_BACKEND_API_KEY}
service:
pipelines:
traces:
receivers: [github]
exporters: [otlp]
“`
One thing that catches people off guard: that `scrapers` block looks unrelated to tracing, and it is — it belongs to a separate GraphQL/REST metrics feature the same receiver provides. However, the configuration fails validation without at least a dummy entry, even if all you want is the webhook side. It’s an easy twenty minutes to lose the first time you set it up.
Point the exporter at Tempo, Jaeger, Datadog, or whatever your team already uses — it just works. That’s the actual benefit of using OTLP rather than a vendor-specific format. The choice of backend is genuinely the least interesting decision in the entire setup.
—
## Things to Sort Out Before Deployment
A few decisions are worth making upfront, because the configuration alone won’t force you to think about them.
**Public endpoint and security.** The collector needs a publicly reachable endpoint since GitHub has to deliver webhooks to it. Plan for IP allowlisting or a WAF restricted to GitHub’s webhook source ranges rather than relying on the shared secret as your only line of defense. There’s also a GitHub App option if you’d rather not manage a shared secret directly — worth exploring if secret rotation across many services is already a headache for your team.
**Organization admin access.** Setting up an organization-level webhook requires org admin permissions. Confirm this early rather than discovering it mid-rollout.
**GitHub Enterprise Server.** If you’re running GitHub Enterprise Server rather than github.com, validate that webhook delivery behaves the same way in your environment before assuming this is a drop-in replacement.
None of these items are difficult — they’re just easy to skip past when you’re excited about the zero-instrumentation promise. Sort them out early and it becomes a one-time cost: point one organization-level webhook at the collector and every repository in the organization is covered from that moment on, including repositories that don’t exist yet. Nobody has to remember to flip a switch.
—
## Sizing It Before You Build It
Walking through the sizing methodology matters, because “just turn on tracing for everything” is a reliable path to an unwelcome bill or an awkward conversation with whoever controls the tracing budget.
Start by scanning the organization for total repository count, then immediately set that number aside. On its own, it’s nearly meaningless for organizations of any real size. Most teams carry a long tail of dormant, forked, archived, or abandoned repositories that inflate the headline count without generating meaningful CI traffic. What actually matters is the active slice: how many repositories had genuine workflow activity in a representative week.
From there, extrapolate logically. Active repository count multiplied by average runs per repository gives you expected workflow volume. Workflow volume multiplied by average steps per workflow gives you expected span volume. Span volume multiplied by typical payload size gives you expected daily data volume. Compare that against whatever tracing volume your infrastructure already handles for application traces, and in most organizations, CI trace volume turns out to be a rounding error.
The comparison itself is the point, not any specific number. What generalizes is the method: measure real activity instead of headline repository counts, and approach the conversation with a comparison rather than an assertion.
—
## Getting Buy-In
The technical build is the straightforward part. The harder part is justifying the data volume to whoever owns the tracing budget — especially when cost concerns are already circulating about the backend service. Showing up with an actual sizing exercise rather than “trust me, it’s small” transforms that conversation from a drawn-out negotiation into a five-minute discussion. Nobody needs to take your word for “it’s small” when they can see it sitting next to the tracing volume they’re already paying for without batting an eye.
It’s also worth remembering that standing up a new observability project is as much an ownership question as a technical one. Someone needs to actually own the collector, the webhook, and the alerting rules going forward. Sorting that out early prevents the awkward moment three months later when something breaks and nobody is sure whose pager it belongs to.
—
## Why This Approach Is Worth the Effort
The zero-instrumentation aspect is where the entire value proposition lives. New repositories become observable the moment they’re created, not the moment someone remembers to add tracing to them. And because everything lands as proper OpenTelemetry traces, CI health lives in the same tool as your application traces — so a slow deployment and a slow downstream service can be correlated instead of investigated across two separate dashboards by two different people who don’t talk to each other until Thursday.
If you’re running self-hosted runners on the Actions Runner Controller, it’s worth being explicit about what this does and doesn’t replace. ARC’s own metrics tell you about your runner fleet — how many pods exist, whether autoscaling is keeping up, how deep the queue is. This approach tells you about your workflows — why a specific run was slow, which ones are flaky, where the time actually went. Queue depth and queue time are practically the same question asked from two different vantage points. Running both gives you the complete picture; picking just one leaves a blind spot.
—
## Frequently Asked Questions
**Q: Do I need to install anything inside my repositories?**
A: No. The entire setup operates at the organization level through webhooks. No workflow files, runner configurations, or repository-level changes are required.
**Q: What happens for repositories created after the webhook is set up?**
A: They’re automatically covered. Since the webhook is organization-scoped, every new repository inherits observability the moment it’s created.
**Q: Is the githubreceiver component production-ready?**
A: It’s currently at alpha stability as a contrib component, meaning the configuration surface can change between versions. Pinning to a specific collector version rather than tracking latest is recommended, along with reviewing the changelog before any upgrades.
**Q: Can I use this alongside GitHub’s native insights?**
A: Absolutely. This approach complements GitHub’s per-repository views by adding cross-organization aggregation, correlation, and alerting capabilities on top.
**Q: What tracing backends work with this setup?**
A: Any backend that accepts OTLP — Tempo, Jaeger, Datadog, Honeycomb, and others all work. The choice of backend is independent of the collection mechanism.
**Q: Does this replace ARC metrics for self-hosted runners?**
A: No. They operate at different layers. ARC metrics cover the runner fleet (pod counts, autoscaling, queue depth). This covers the workflow level (why a specific run was slow, where time was spent). Both are valuable.
**Q: What about security — is the webhook secret enough?**
A: The shared secret is a good baseline, but for stronger security posture, combine it with IP allowlisting or a WAF restricted to GitHub’s webhook source ranges. A GitHub App is another option worth evaluating.
**Q: How much data volume should I realistically expect?**
A: It varies by organization, but the methodology in this article — measuring active repository count, multiply by runs and steps, compare against existing application trace volume — will give you a reliable estimate. For most organizations, CI trace volume is a small fraction of total tracing throughput.
—
## Conclusion
Getting organization-wide visibility into GitHub Actions CI health doesn’t require a massive infrastructure project or buy-in from every team. By leveraging GitHub’s existing webhook events and OpenTelemetry’s standard data model, you can collect meaningful traces from every workflow in the organization from a single collection point. The zero-instrumentation approach means new repositories are observable immediately, and the use of standard OTLP exports ensures your CI data lives alongside your application data in whatever tracing backend you already trust.
The key takeaways are straightforward: listen to what GitHub is already telling you, size your expectations with real activity data rather than repository counts, sort out ownership and security early, and let the standardization of OTLP do the heavy lifting for backend flexibility.
Thank you for reading



