A swarm-ci-metrics host unit on a 5-minute timer lists every forge repo's Actions runs as the new read-only ci-metrics account and pushes each finished run's duration and queue wait over OTLP, stamped at the run's stop time. The first pass backfills from run 1. swarm-controller mints the account's token into bao and keeps a ci-metrics team with read on the Actions unit in every organisation. Closes #5376
410 lines
10 KiB
JSON
410 lines
10 KiB
JSON
{
|
|
"uid": "hyperhive-swarm-ci",
|
|
"title": "hyperhive · CI runs",
|
|
"description": "Forge Actions run time and queue wait, one sample per finished run, per repo and workflow.",
|
|
"tags": ["hyperhive", "ci"],
|
|
"timezone": "utc",
|
|
"schemaVersion": 39,
|
|
"version": 1,
|
|
"editable": true,
|
|
"refresh": "5m",
|
|
"time": {
|
|
"from": "now-30d",
|
|
"to": "now"
|
|
},
|
|
"templating": {
|
|
"list": [
|
|
{
|
|
"name": "repo",
|
|
"label": "Repo",
|
|
"type": "query",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"query": "label_values({__name__=\"hyperhive.ci.run.duration\"}, repo)",
|
|
"refresh": 2,
|
|
"includeAll": true,
|
|
"allValue": ".*",
|
|
"multi": true,
|
|
"current": {
|
|
"text": "All",
|
|
"value": "$__all"
|
|
},
|
|
"sort": 1
|
|
},
|
|
{
|
|
"name": "workflow",
|
|
"label": "Workflow",
|
|
"type": "query",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"query": "label_values({__name__=\"hyperhive.ci.run.duration\", repo=~\"$repo\"}, workflow)",
|
|
"refresh": 2,
|
|
"includeAll": true,
|
|
"allValue": ".*",
|
|
"multi": true,
|
|
"current": {
|
|
"text": "All",
|
|
"value": "$__all"
|
|
},
|
|
"sort": 1
|
|
}
|
|
]
|
|
},
|
|
"panels": [
|
|
{
|
|
"id": 1,
|
|
"type": "timeseries",
|
|
"title": "Run duration, successful runs",
|
|
"description": "Mean and 90th percentile of stopped minus started, over the runs that ended in each interval.",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"interval": "1h",
|
|
"gridPos": {
|
|
"h": 9,
|
|
"w": 12,
|
|
"x": 0,
|
|
"y": 0
|
|
},
|
|
"targets": [
|
|
{
|
|
"refId": "A",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "avg(last_over_time({__name__=\"hyperhive.ci.run.duration\", repo=~\"$repo\", workflow=~\"$workflow\", outcome=\"success\"}[$__interval]))",
|
|
"legendFormat": "mean"
|
|
},
|
|
{
|
|
"refId": "B",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "quantile(0.9, last_over_time({__name__=\"hyperhive.ci.run.duration\", repo=~\"$repo\", workflow=~\"$workflow\", outcome=\"success\"}[$__interval]))",
|
|
"legendFormat": "p90"
|
|
}
|
|
],
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"unit": "s",
|
|
"color": {
|
|
"mode": "palette-classic"
|
|
},
|
|
"custom": {
|
|
"drawStyle": "line",
|
|
"lineWidth": 2,
|
|
"fillOpacity": 0,
|
|
"showPoints": "auto",
|
|
"spanNulls": false,
|
|
"axisSoftMin": 0
|
|
}
|
|
},
|
|
"overrides": []
|
|
},
|
|
"options": {
|
|
"legend": {
|
|
"displayMode": "list",
|
|
"placement": "bottom",
|
|
"showLegend": true,
|
|
"calcs": []
|
|
},
|
|
"tooltip": {
|
|
"mode": "multi",
|
|
"sort": "desc"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": 2,
|
|
"type": "timeseries",
|
|
"title": "Queue wait",
|
|
"description": "Started minus created: how long each run waited for a runner, mean and longest per interval.",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"interval": "1h",
|
|
"gridPos": {
|
|
"h": 9,
|
|
"w": 12,
|
|
"x": 12,
|
|
"y": 0
|
|
},
|
|
"targets": [
|
|
{
|
|
"refId": "A",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "avg(last_over_time({__name__=\"hyperhive.ci.run.queue_wait\", repo=~\"$repo\", workflow=~\"$workflow\"}[$__interval]))",
|
|
"legendFormat": "mean"
|
|
},
|
|
{
|
|
"refId": "B",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "max(last_over_time({__name__=\"hyperhive.ci.run.queue_wait\", repo=~\"$repo\", workflow=~\"$workflow\"}[$__interval]))",
|
|
"legendFormat": "longest"
|
|
}
|
|
],
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"unit": "s",
|
|
"color": {
|
|
"mode": "palette-classic"
|
|
},
|
|
"custom": {
|
|
"drawStyle": "line",
|
|
"lineWidth": 2,
|
|
"fillOpacity": 0,
|
|
"showPoints": "auto",
|
|
"spanNulls": false,
|
|
"axisSoftMin": 0
|
|
}
|
|
},
|
|
"overrides": []
|
|
},
|
|
"options": {
|
|
"legend": {
|
|
"displayMode": "list",
|
|
"placement": "bottom",
|
|
"showLegend": true,
|
|
"calcs": []
|
|
},
|
|
"tooltip": {
|
|
"mode": "multi",
|
|
"sort": "desc"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": 3,
|
|
"type": "timeseries",
|
|
"title": "Runs per day by outcome",
|
|
"description": "Finished runs per UTC day. Cancelled runs are not counted.",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"interval": "1d",
|
|
"gridPos": {
|
|
"h": 9,
|
|
"w": 12,
|
|
"x": 0,
|
|
"y": 9
|
|
},
|
|
"targets": [
|
|
{
|
|
"refId": "A",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "count by (outcome) (last_over_time({__name__=\"hyperhive.ci.run.duration\", repo=~\"$repo\", workflow=~\"$workflow\"}[$__interval]))",
|
|
"legendFormat": "{{outcome}}"
|
|
}
|
|
],
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"unit": "short",
|
|
"decimals": 0,
|
|
"color": {
|
|
"mode": "palette-classic"
|
|
},
|
|
"custom": {
|
|
"drawStyle": "bars",
|
|
"lineWidth": 1,
|
|
"fillOpacity": 80,
|
|
"showPoints": "never",
|
|
"stacking": {
|
|
"mode": "normal",
|
|
"group": "A"
|
|
},
|
|
"axisSoftMin": 0
|
|
}
|
|
},
|
|
"overrides": [
|
|
{
|
|
"matcher": {
|
|
"id": "byName",
|
|
"options": "success"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "color",
|
|
"value": {
|
|
"mode": "fixed",
|
|
"fixedColor": "green"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": {
|
|
"id": "byName",
|
|
"options": "failure"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "color",
|
|
"value": {
|
|
"mode": "fixed",
|
|
"fixedColor": "red"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"legend": {
|
|
"displayMode": "list",
|
|
"placement": "bottom",
|
|
"showLegend": true,
|
|
"calcs": ["sum"]
|
|
},
|
|
"tooltip": {
|
|
"mode": "multi",
|
|
"sort": "desc"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": 4,
|
|
"type": "table",
|
|
"title": "Duration per PR",
|
|
"description": "Per PR (or ref, for runs not on a PR) over the time range: run time of its successful runs.",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"gridPos": {
|
|
"h": 9,
|
|
"w": 12,
|
|
"x": 12,
|
|
"y": 9
|
|
},
|
|
"targets": [
|
|
{
|
|
"refId": "A",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "avg by (pr) (last_over_time({__name__=\"hyperhive.ci.run.duration\", repo=~\"$repo\", workflow=~\"$workflow\", outcome=\"success\"}[$__range]))",
|
|
"format": "table",
|
|
"instant": true
|
|
},
|
|
{
|
|
"refId": "B",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "max by (pr) (last_over_time({__name__=\"hyperhive.ci.run.duration\", repo=~\"$repo\", workflow=~\"$workflow\", outcome=\"success\"}[$__range]))",
|
|
"format": "table",
|
|
"instant": true
|
|
},
|
|
{
|
|
"refId": "C",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "count by (pr) (last_over_time({__name__=\"hyperhive.ci.run.duration\", repo=~\"$repo\", workflow=~\"$workflow\"}[$__range]))",
|
|
"format": "table",
|
|
"instant": true
|
|
},
|
|
{
|
|
"refId": "D",
|
|
"datasource": {
|
|
"type": "prometheus",
|
|
"uid": "@datasourceUid@"
|
|
},
|
|
"expr": "count by (pr) (last_over_time({__name__=\"hyperhive.ci.run.duration\", repo=~\"$repo\", workflow=~\"$workflow\", outcome=\"failure\"}[$__range]))",
|
|
"format": "table",
|
|
"instant": true
|
|
}
|
|
],
|
|
"transformations": [
|
|
{
|
|
"id": "merge",
|
|
"options": {}
|
|
},
|
|
{
|
|
"id": "organize",
|
|
"options": {
|
|
"excludeByName": {
|
|
"Time": true
|
|
},
|
|
"renameByName": {
|
|
"pr": "PR",
|
|
"Value #A": "Mean (success)",
|
|
"Value #B": "Longest (success)",
|
|
"Value #C": "Runs",
|
|
"Value #D": "Failed runs"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "sortBy",
|
|
"options": {
|
|
"sort": [
|
|
{
|
|
"field": "PR",
|
|
"desc": true
|
|
}
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"custom": {
|
|
"align": "auto"
|
|
}
|
|
},
|
|
"overrides": [
|
|
{
|
|
"matcher": {
|
|
"id": "byRegexp",
|
|
"options": "^(Mean|Longest).*"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "unit",
|
|
"value": "s"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": {
|
|
"id": "byRegexp",
|
|
"options": "^(Runs|Failed runs)$"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "decimals",
|
|
"value": 0
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"showHeader": true,
|
|
"cellHeight": "sm"
|
|
}
|
|
}
|
|
]
|
|
}
|