feat(coordinator): business metrics — jobs/tasks/workers by status

A scrape-time collector reports scimesh_tasks/jobs/workers gauges keyed by
status, sourced from cheap GROUP BY queries (StatsRepo), zero-filled across all
known statuses so the dashboard shows flat zeros instead of gaps. A failed
query yields no samples for that scrape rather than crashing it.

Metrics is now built in main so the DB-backed collector can be registered
(NewServer takes *metrics.Metrics; nil self-provisions for tests). Grafana
dashboard gains a Domain state row: tasks/jobs/workers by status and a queue-
depth stat.
This commit is contained in:
Efremenko Arhip
2026-07-26 22:16:35 +03:00
parent e9cf6f0842
commit dcabfcd0c3
7 changed files with 265 additions and 4 deletions
@@ -83,6 +83,72 @@
"legendFormat": "rss"
}
]
},
{
"type": "row",
"title": "Domain state",
"collapsed": false,
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 16 }
},
{
"type": "timeseries",
"title": "Tasks by status",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 17 },
"fieldConfig": { "defaults": { "unit": "short", "custom": { "stacking": { "mode": "normal" }, "fillOpacity": 30 } }, "overrides": [] },
"targets": [
{
"refId": "A",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"expr": "scimesh_tasks",
"legendFormat": "{{status}}"
}
]
},
{
"type": "timeseries",
"title": "Jobs by status",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 17 },
"fieldConfig": { "defaults": { "unit": "short", "custom": { "stacking": { "mode": "normal" }, "fillOpacity": 30 } }, "overrides": [] },
"targets": [
{
"refId": "A",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"expr": "scimesh_jobs",
"legendFormat": "{{status}}"
}
]
},
{
"type": "stat",
"title": "Queue depth (pending tasks)",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"gridPos": { "h": 8, "w": 6, "x": 0, "y": 25 },
"fieldConfig": { "defaults": { "unit": "short", "color": { "mode": "thresholds" }, "thresholds": { "steps": [ { "color": "green", "value": null }, { "color": "yellow", "value": 50 }, { "color": "red", "value": 500 } ] } }, "overrides": [] },
"targets": [
{
"refId": "A",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"expr": "sum(scimesh_tasks{status=\"pending\"})",
"legendFormat": "pending"
}
]
},
{
"type": "timeseries",
"title": "Workers by status",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"gridPos": { "h": 8, "w": 18, "x": 6, "y": 25 },
"fieldConfig": { "defaults": { "unit": "short", "custom": { "stacking": { "mode": "normal" }, "fillOpacity": 30 } }, "overrides": [] },
"targets": [
{
"refId": "A",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"expr": "scimesh_workers",
"legendFormat": "{{status}}"
}
]
}
]
}