Copy as Markdown[Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fintegrations%2Fpull%2Fgithub%2Fworkflow-metrics.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fintegrations%2Fpull%2Fgithub%2Fworkflow-metrics.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)

# GitHub workflow metrics

When **Workflow metrics** is selected in the [GitHub integration](https://coralogix.com/docs/integrations/pull/github.md)'s **Github Events** panel, Coralogix turns every completed GitHub Actions workflow run and job into metrics: how many ran, how they concluded, how long they took, and how long they waited for a runner. The metrics are produced from the same events the integration writes as logs, so there is nothing to add to your workflows.

## What you need[​](#what-you-need "Direct link to What you need")

* The **GitHub events** capability, set up as described in the [GitHub integration](https://coralogix.com/docs/integrations/pull/github.md#set-up-the-integration).
* The `workflow_run` and `workflow_job` event types. They are included when **All event types** is on. If you select event types, select both.
* The **Actions: Read** permission granted to the app, which unlocks those two event types. See [GitHub app permissions](https://coralogix.com/docs/integrations/pull/github/permissions.md#github-events).

## Turn on workflow metrics[​](#turn-on-workflow-metrics "Direct link to Turn on workflow metrics")

1. Open the GitHub integration and go to its **Github Events** panel.
2. Select **Workflow metrics**.
3. Optional: select **Workflow step metrics** to also measure each step of every job. See [Step metrics](#step-metrics).
4. Save the panel.

The setting takes effect when event routing is next refreshed, which can take up to 15 minutes. Only runs and jobs that complete after that are counted; earlier ones are not backfilled.

## Metrics[​](#metrics "Direct link to Metrics")

A run or a job is counted when it completes. Queued and in-progress events produce no metrics.

A job that GitHub skips, because its `if:` condition is false or a job it `needs` failed, never runs. It is counted only in `github_workflow_job_total`, with conclusion `skipped`. The job duration and queue histograms and `github_workflow_overall_job_count_total` include only jobs that ran.

| Metric                                       | Type      | Labels                                                          | Measures                                                                          |
| -------------------------------------------- | --------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `github_workflow_run_total`                  | Counter   | `repository`, `workflow`, `conclusion`                          | Completed workflow runs                                                           |
| `github_workflow_run_duration_seconds`       | Histogram | `repository`, `workflow`, `conclusion`                          | From the run's start to its completion                                            |
| `github_workflow_run_last_status`            | Gauge     | `repository`, `workflow`, `conclusion`                          | `1` on the conclusion of the workflow's latest run, `0` on every other conclusion |
| `github_workflow_job_total`                  | Counter   | `repository`, `workflow`, `job`, `runner`, `conclusion`         | Completed jobs, including skipped ones                                            |
| `github_workflow_job_duration_seconds`       | Histogram | `repository`, `workflow`, `job`, `runner`, `conclusion`         | From the job's start to its completion                                            |
| `github_workflow_job_queue_duration_seconds` | Histogram | `repository`, `workflow`, `job`, `runner`, `conclusion`         | From the job's creation to its start, mostly time spent waiting for a runner      |
| `github_workflow_overall_job_count_total`    | Counter   | `repository`                                                    | Completed jobs that ran                                                           |
| `github_workflow_successful_job_count_total` | Counter   | `repository`                                                    | Jobs that concluded `success`                                                     |
| `github_workflow_failed_job_count_total`     | Counter   | `repository`                                                    | Jobs that concluded `failure`                                                     |
| `github_workflow_step_duration_seconds`      | Histogram | `repository`, `workflow`, `job`, `runner`, `step`, `conclusion` | From the step's start to its completion. Only with **Workflow step metrics**      |

Each histogram is queryable as `<metric>_bucket`, `<metric>_sum`, and `<metric>_count`.

### Labels[​](#labels "Direct link to Labels")

* `repository`: the repository's full name, such as `acme/widgets`.
* `workflow`: the workflow's name, as shown in the GitHub **Actions** tab.
* `job`: the job's name. Each cell of a matrix job has its own name, such as `test (ubuntu-latest, 22)`, and its own series.
* `runner`: the labels the job's `runs-on` asked for, sorted and comma-separated, such as `ubuntu-latest` or `gpu,linux,self-hosted`. Grouping job queue times by `runner` shows which kind of runner jobs wait for.
* `step`: the step's name, as shown in the job's log in GitHub, such as `Run actions/checkout@v5`. On step metrics, `conclusion` is the step's own conclusion, so a skipped step of a failed job is `skipped`.
* `conclusion`: one of `success`, `failure`, `cancelled`, `timed_out`, `skipped`, `neutral`, `action_required`, `stale`, or `unknown`. `unknown` stands for any conclusion GitHub reports outside that list. GitHub reports a job that exceeds its `timeout-minutes` as `cancelled`, and its run too, so timeouts are counted as cancellations.

Label values longer than 256 characters are cut at 256.

### Last status[​](#last-status "Direct link to Last status")

`github_workflow_run_last_status` has one series for each of the nine conclusions of a workflow. Exactly one of them is `1`: the conclusion of the workflow's most recently completed run. A re-run that succeeds after a failure moves the `1` from `failure` to `success`.

### Step metrics[​](#step-metrics "Direct link to Step metrics")

**Workflow step metrics** adds `github_workflow_step_duration_seconds`, one series for every step name and conclusion of every job. Steps are where a slow job spends its time, so this shows which step got slower. It is also the largest contributor to the number of series: a workflow with five jobs of ten steps each has at least fifty step series, more for every matrix cell. It is off by default, is available only while **Workflow metrics** is selected, and turning it off leaves the other workflow metrics unchanged.

### Histogram buckets[​](#histogram-buckets "Direct link to Histogram buckets")

Bucket upper bounds, in seconds:

| Histograms                  | Bounds                                                  |
| --------------------------- | ------------------------------------------------------- |
| Run and job durations       | 10, 30, 60, 120, 300, 600, 900, 1800, 3600, 7200, 21600 |
| Run and job queue durations | 1, 5, 15, 30, 60, 120, 300, 600, 1800                   |
| Step durations              | 1, 5, 15, 30, 60, 300, 900, 1800                        |

## When points are published[​](#when-points-are-published "Direct link to When points are published")

Coralogix publishes workflow metrics once a minute, at the start of each minute. A minute's points carry what Coralogix had received by then, so a completed run usually shows up within one to two minutes. Each point is timestamped with the minute it is published for, which can be up to a minute after the run completed. Use `github_workflow_run_duration_seconds` and the other duration metrics for exact timings.

The values are cumulative: a counter holds the total since the series started, and a histogram holds all observations since then.

### Sparse activity[​](#sparse-activity "Direct link to Sparse activity")

A series is published only in minutes when it has new data. Between runs nothing is sent for it, so in a query it ends at its last point and is shown as stale once that point is older than the query's lookback window.

When new data arrives within one hour of the series' previous point, the minutes in between are filled with the earlier value, so the series stays continuous across short pauses. A pause longer than an hour stays a gap: the series reappears with its new total once the next run completes.

Write queries that tolerate gaps by looking over a window:

```
# Runs per workflow in the last hour, by conclusion

sum by (repository, workflow, conclusion) (increase(github_workflow_run_total[1h]))



# Latest conclusion of each workflow, even if its last run was hours ago

last_over_time(github_workflow_run_last_status[1d]) == 1



# 95th percentile job queue time over the last 6 hours, by the kind of runner jobs waited for

histogram_quantile(0.95, sum by (le, runner) (increase(github_workflow_job_queue_duration_seconds_bucket[6h])))
```

For alerts on infrequent workflows, use windows longer than the time between their runs. A window of a few minutes over a workflow that runs hourly is empty most of the time.

### Series restarts[​](#series-restarts "Direct link to Series restarts")

A series that receives no events for seven days is removed. If the workflow runs again later, its series starts from zero. Functions such as `increase()` and `rate()` treat this as a counter reset.

## Duplicates, re-runs, and delivery[​](#duplicates-re-runs-and-delivery "Direct link to Duplicates, re-runs, and delivery")

* **Redeliveries are counted once.** GitHub can deliver the same event more than once: when you redeliver it from the app's settings, and occasionally on its own, under a new delivery id. A run's completion is counted once per run attempt, and a job's completion once per job, within three days.
* **Re-runs are counted as runs.** Re-running a workflow or a job produces a new completion, which is counted in addition to the original one.
* **Delayed points keep their minute.** If Coralogix cannot deliver a minute's points to your account right away, it retries them for up to a day. Points delivered late keep the minute they were published for, so graphs show no gap once they arrive.
* **Blocked metrics are dropped.** While metrics ingestion is blocked for your account, for example by its quota, workflow metrics are dropped and not sent later.
* **Metrics and logs are independent.** Workflow metrics are produced even when the event's log is [truncated](https://coralogix.com/docs/integrations/pull/github.md#large-events-are-truncated) or blocked.

## The Coralogix GitHub Action[​](#the-coralogix-github-action "Direct link to The Coralogix GitHub Action")

`github_workflow_overall_job_count_total`, `github_workflow_successful_job_count_total`, and `github_workflow_failed_job_count_total` use the names of the metrics sent by the [Coralogix GitHub Action](https://coralogix.com/docs/integrations/ci/cd/github-actions.md). The integration's series carry a `repository` label in place of the action's service name label, so queries that filter or group by the service name need that label changed when you move from the action to the integration.

If both the action and the integration report the same repository, each job is counted twice. Use one of them per repository, or filter your queries by the labels that tell the two apart.

## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting")

| Symptom                                     | Cause                                                                                                      | Resolution                                                                                                            |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| No workflow metrics arrive                  | **Workflow metrics** is not selected, routing has not refreshed yet, or no run has completed since.        | Confirm the setting, wait up to 15 minutes, then complete a workflow run in a repository covered by the installation. |
| Logs arrive, but no metrics for some events | `workflow_run` or `workflow_job` is not among the selected event types, or the events are not completions. | Select both event types, or turn on **All event types**. Only completed runs and jobs produce metrics.                |
| A series disappears between runs            | No new data for that series.                                                                               | Expected. Query over a window, as in [Sparse activity](#sparse-activity).                                             |
| Job counts are double what GitHub shows     | The Coralogix GitHub Action reports the same jobs.                                                         | See [The Coralogix GitHub Action](#the-coralogix-github-action).                                                      |
| Runs that timed out show as `cancelled`     | GitHub reports a job that exceeds its `timeout-minutes`, and its run, as `cancelled`.                      | Expected. The timeout is visible only in the job's annotations in GitHub.                                             |
| A counter dropped to a low value            | The series was removed after seven days without events and restarted.                                      | Expected. Use `increase()` or `rate()`, which handle counter resets.                                                  |

## Related resources[​](#related-resources "Direct link to Related resources")

* [GitHub integration](https://coralogix.com/docs/integrations/pull/github.md)
* [GitHub app permissions](https://coralogix.com/docs/integrations/pull/github/permissions.md)
* [Coralogix GitHub Action](https://coralogix.com/docs/integrations/ci/cd/github-actions.md)
