feat(observabilité) — jobs d'analyse Kadans : scrape du worker laptop + dashboard Grafana #15

Merged
arcodange merged 1 commits from arcodange/observabilite-kadans into main 2026-07-24 21:24:41 +02:00
2 changed files with 139 additions and 0 deletions
+123
View File
@@ -724,6 +724,14 @@ grafana: &grafana_config
editable: true editable: true
options: options:
path: /var/lib/grafana/dashboards/prospection path: /var/lib/grafana/dashboards/prospection
- name: 'kadans'
orgId: 1
folder: 'Kadans'
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards/kadans
# - name: 'default' # - name: 'default'
# orgId: 1 # orgId: 1
@@ -778,6 +786,121 @@ grafana: &grafana_config
k8s-views-pods: k8s-views-pods:
url: https://raw.githubusercontent.com/dotdc/grafana-dashboards-kubernetes/master/dashboards/k8s-views-pods.json url: https://raw.githubusercontent.com/dotdc/grafana-dashboards-kubernetes/master/dashboards/k8s-views-pods.json
token: '' token: ''
# Jobs d'analyse Kadans : la file de la façade (pod kadans-jobs, annoté
# prometheus.io/*) + le worker du LAPTOP (cible statique kadans-worker-mac).
# Couleurs de STATUT sémantiques (pending/running/done/failed) — jamais
# recyclées pour de l'identité ; le sommeil du Mac est un ÉTAT, pas une
# alerte (« sa disponibilité n'impacte que la latence »).
kadans:
kadans-jobs:
json: |
{
"annotations": { "list": [] },
"editable": true,
"graphTooltip": 1,
"schemaVersion": 39,
"tags": ["kadans", "jobs", "arcodange"],
"title": "Kadans — jobs d'analyse (façade + worker Mac)",
"uid": "kadans-jobs-analyse",
"time": { "from": "now-24h", "to": "now" },
"panels": [
{
"type": "stat", "title": "Worker Mac", "id": 1,
"gridPos": { "h": 5, "w": 6, "x": 0, "y": 0 },
"targets": [{ "expr": "up{job=\"kadans-worker-mac\"}", "refId": "A" }],
"fieldConfig": { "defaults": {
"mappings": [
{ "type": "value", "options": { "1": { "text": "En écoute", "color": "green" }, "0": { "text": "Endormi", "color": "text" } } },
{ "type": "special", "options": { "match": "null", "result": { "text": "Endormi", "color": "text" } } }
],
"thresholds": { "mode": "absolute", "steps": [{ "color": "text", "value": null }] }
}, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Dernier poll (il y a)", "id": 2,
"gridPos": { "h": 5, "w": 6, "x": 6, "y": 0 },
"targets": [{ "expr": "time() - kadans_worker_dernier_poll_timestamp_seconds", "refId": "A" }],
"fieldConfig": { "defaults": {
"unit": "s", "decimals": 0,
"thresholds": { "mode": "absolute", "steps": [
{ "color": "green", "value": null }, { "color": "yellow", "value": 600 }
] }
}, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Jobs en attente", "id": 3,
"gridPos": { "h": 5, "w": 6, "x": 12, "y": 0 },
"targets": [{ "expr": "sum(kadans_jobs_jobs{statut=\"pending\"})", "refId": "A" }],
"fieldConfig": { "defaults": {
"thresholds": { "mode": "absolute", "steps": [{ "color": "text", "value": null }] }
}, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "area", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Plus ancien job en attente", "id": 4,
"gridPos": { "h": 5, "w": 6, "x": 18, "y": 0 },
"targets": [{ "expr": "kadans_jobs_plus_ancien_pending_age_seconds", "refId": "A" }],
"fieldConfig": { "defaults": {
"unit": "s", "decimals": 0,
"thresholds": { "mode": "absolute", "steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 3600 },
{ "color": "red", "value": 86400 }
] }
}, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "timeseries", "title": "La file, par statut", "id": 5,
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 5 },
"targets": [{ "expr": "kadans_jobs_jobs", "legendFormat": "{{statut}}", "refId": "A" }],
"fieldConfig": { "defaults": {
"custom": { "lineWidth": 2, "fillOpacity": 8, "pointSize": 4 }, "min": 0
}, "overrides": [
{ "matcher": { "id": "byName", "options": "pending" }, "properties": [{ "id": "color", "value": { "mode": "fixed", "fixedColor": "yellow" } }] },
{ "matcher": { "id": "byName", "options": "running" }, "properties": [{ "id": "color", "value": { "mode": "fixed", "fixedColor": "blue" } }] },
{ "matcher": { "id": "byName", "options": "done" }, "properties": [{ "id": "color", "value": { "mode": "fixed", "fixedColor": "green" } }] },
{ "matcher": { "id": "byName", "options": "failed" }, "properties": [{ "id": "color", "value": { "mode": "fixed", "fixedColor": "red" } }] }
] },
"options": { "legend": { "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "multi" } }
},
{
"type": "timeseries", "title": "Publications (par heure)", "id": 6,
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 5 },
"targets": [{ "expr": "increase(kadans_jobs_publies_total[1h])", "legendFormat": "{{issue}}", "refId": "A" }],
"fieldConfig": { "defaults": {
"custom": { "lineWidth": 2, "fillOpacity": 8, "pointSize": 4 }, "min": 0, "decimals": 0
}, "overrides": [
{ "matcher": { "id": "byName", "options": "done" }, "properties": [{ "id": "color", "value": { "mode": "fixed", "fixedColor": "green" } }] },
{ "matcher": { "id": "byName", "options": "failed" }, "properties": [{ "id": "color", "value": { "mode": "fixed", "fixedColor": "red" } }] }
] },
"options": { "legend": { "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "multi" } }
},
{
"type": "timeseries", "title": "Lanes exécutées par le worker (par heure)", "id": 7,
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 13 },
"targets": [{ "expr": "increase(kadans_worker_lanes_total[1h])", "legendFormat": "{{lane}} — {{issue}}", "refId": "A" }],
"fieldConfig": { "defaults": {
"custom": { "lineWidth": 2, "fillOpacity": 8, "pointSize": 4 }, "min": 0, "decimals": 0
}, "overrides": [] },
"options": { "legend": { "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "multi" } }
},
{
"type": "timeseries", "title": "Durée moyenne d'une lane", "id": 8,
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 13 },
"targets": [{
"expr": "increase(kadans_worker_lane_duree_seconds_sum[1h]) / increase(kadans_worker_lane_duree_seconds_count[1h])",
"legendFormat": "{{lane}}", "refId": "A"
}],
"fieldConfig": { "defaults": {
"unit": "s", "custom": { "lineWidth": 2, "fillOpacity": 0, "pointSize": 5 }, "min": 0
}, "overrides": [] },
"options": { "legend": { "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "multi" } }
}
]
}
prospection: prospection:
prospection: prospection:
json: | json: |
+16
View File
@@ -819,6 +819,22 @@ prometheus: &prometheus_config
static_configs: static_configs:
- targets: - targets:
- localhost:9090 - localhost:9090
# Le worker d'analyse Kadans sur le LAPTOP du fondateur (tier 1 VOLATILE,
# kadans-jobs cmd/worker, /metrics stdlib sur :9105). Un scrape en échec
# n'est PAS un incident : le Mac dort — `up == 0` raconte exactement ça
# (latence des analyses, jamais une indisponibilité produit). Ne PAS
# alerter sur cette cible.
# ⚠ IP DHCP : réserver 192.168.1.103 pour le Mac au routeur (ou remplacer
# par un nom résolvable du LAN) — sinon la cible dérive au renouvellement.
kadans-worker-mac:
enabled: true
job_name: "kadans-worker-mac"
static_configs:
- targets:
- 192.168.1.103:9105
labels:
tier: laptop
app: kadans-worker
kubernetes-api-servers: kubernetes-api-servers:
enabled: true enabled: true
job_name: "" job_name: ""