feat(monitoring): dashboard Grafana + règles d'alerte prospection
Helm Charts / Detect changed charts (push) Successful in 22s
Helm Charts / Library charts tool (push) Has been skipped
Helm Charts / Application charts pgcat (push) Has been skipped
Helm Charts / Detect changed charts (pull_request) Successful in 21s
Helm Charts / Library charts tool (pull_request) Has been skipped
Helm Charts / Application charts pgcat (pull_request) Has been skipped

Consomme les métriques poussées par le pipeline prospection au Pushgateway
(job=prospection, déjà scrapé). Additif — n'affecte aucun dashboard existant.

- grafana : provider + dashboard « Prospection — pipeline BI missions » inliné
  (grafana.dashboards.prospection, json) — vue d'ensemble (fraîcheur/statut/durée/
  erreurs/missions/score), collecte par étape (table + historique), modèle de
  données (opportunités A/B, offres/entités), livraison (brief/Telegram) + panneau
  Alertes actives. Inline plutôt que ConfigMap externe : grafana est déployé via un
  HelmChart CRD (tool lib), l'inline évite toute hypothèse de namespace.
- prometheus : groupe d'alertes `prospection` (serverFiles.alerting_rules.yml) —
  RunStale (>25h), RunFailed, StepError, NoOffers, BriefNotSent.

NB : la livraison des alertes (Alertmanager → Telegram) n'est pas câblée dans le
cluster (server.alertmanagers vide, aucun receiver) ; les règles restent visibles
dans Prometheus /alerts + le dashboard. Câblage delivery = décision séparée.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
2026-07-08 19:52:29 +02:00
co-authored by Claude Opus 4.8
parent b4f945c310
commit e6fca752a2
2 changed files with 277 additions and 1 deletions
+224
View File
@@ -703,6 +703,14 @@ grafana: &grafana_config
editable: true editable: true
options: options:
path: /var/lib/grafana/dashboards/grafana-dashboards-kubernetes path: /var/lib/grafana/dashboards/grafana-dashboards-kubernetes
- name: 'prospection'
orgId: 1
folder: 'Prospection'
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards/prospection
# - name: 'default' # - name: 'default'
# orgId: 1 # orgId: 1
@@ -757,6 +765,222 @@ 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: ''
prospection:
prospection:
json: |
{
"__inputs": [],
"annotations": { "list": [] },
"editable": true,
"graphTooltip": 1,
"schemaVersion": 39,
"tags": ["prospection", "arcodange"],
"title": "Prospection — pipeline BI missions",
"uid": "prospection-pipeline",
"time": { "from": "now-14d", "to": "now" },
"refresh": "5m",
"templating": {
"list": [
{
"name": "DS_PROMETHEUS",
"label": "Datasource",
"type": "datasource",
"query": "prometheus",
"current": {},
"hide": 0,
"refresh": 1
}
]
},
"panels": [
{
"type": "row", "title": "Vue d'ensemble du dernier run",
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 1, "collapsed": false
},
{
"type": "stat", "title": "Dernier run réussi il y a", "id": 2,
"gridPos": { "h": 4, "w": 5, "x": 0, "y": 1 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "time() - prospection_run_timestamp_seconds", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": {
"unit": "s",
"thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "yellow", "value": 86400 }, { "color": "red", "value": 90000 } ] }
}, "overrides": [] },
"options": { "colorMode": "background", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] }, "textMode": "auto" }
},
{
"type": "stat", "title": "Statut du run", "id": 3,
"gridPos": { "h": 4, "w": 4, "x": 5, "y": 1 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_run_success", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": {
"mappings": [ { "type": "value", "options": { "0": { "text": "ÉCHEC", "color": "red", "index": 0 }, "1": { "text": "OK", "color": "green", "index": 1 } } } ],
"thresholds": { "mode": "absolute", "steps": [ { "color": "red", "value": null }, { "color": "green", "value": 1 } ] }
}, "overrides": [] },
"options": { "colorMode": "background", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] }, "textMode": "auto" }
},
{
"type": "stat", "title": "Durée du run", "id": 4,
"gridPos": { "h": 4, "w": 5, "x": 9, "y": 1 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_run_duration_seconds", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "unit": "s", "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "yellow", "value": 1200 }, { "color": "red", "value": 1700 } ] } }, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "area", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Étapes en erreur", "id": 5,
"gridPos": { "h": 4, "w": 4, "x": 14, "y": 1 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_run_errors_total", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 1 } ] } }, "overrides": [] },
"options": { "colorMode": "background", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Missions A qualifiées", "id": 6,
"gridPos": { "h": 4, "w": 3, "x": 18, "y": 1 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_opportunities_total{kind=\"A\"}", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "thresholds": { "mode": "absolute", "steps": [ { "color": "red", "value": null }, { "color": "yellow", "value": 1 }, { "color": "green", "value": 10 } ] } }, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "area", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Meilleur score", "id": 7,
"gridPos": { "h": 4, "w": 3, "x": 21, "y": 1 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_opportunity_top_score", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "min": 0, "max": 100, "thresholds": { "mode": "absolute", "steps": [ { "color": "red", "value": null }, { "color": "yellow", "value": 65 }, { "color": "green", "value": 85 } ] } }, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "row", "title": "Collecte par étape",
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 }, "id": 8, "collapsed": false
},
{
"type": "table", "title": "Étapes — dernier run", "id": 9,
"gridPos": { "h": 9, "w": 12, "x": 0, "y": 6 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [
{ "refId": "Statut", "expr": "prospection_step_status", "instant": true, "format": "table", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } },
{ "refId": "Items", "expr": "prospection_step_items", "instant": true, "format": "table", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } },
{ "refId": "Durée", "expr": "prospection_step_duration_seconds", "instant": true, "format": "table", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } }
],
"transformations": [
{ "id": "merge", "options": {} },
{ "id": "organize", "options": {
"excludeByName": { "Time": true, "__name__": true, "job": true, "instance": true },
"renameByName": { "step": "Étape", "Value #Statut": "Statut", "Value #Items": "Items", "Value #Durée": "Durée (s)" },
"indexByName": { "step": 0, "Value #Statut": 1, "Value #Items": 2, "Value #Durée": 3 }
} }
],
"fieldConfig": { "defaults": { "custom": { "align": "auto" } }, "overrides": [
{ "matcher": { "id": "byName", "options": "Statut" }, "properties": [
{ "id": "mappings", "value": [ { "type": "value", "options": { "0": { "text": "⛔ erreur", "color": "red", "index": 0 }, "1": { "text": "✅ ok", "color": "green", "index": 1 }, "2": { "text": "⏭️ skip", "color": "blue", "index": 2 } } } ] },
{ "id": "custom.cellOptions", "value": { "type": "color-text" } }
] },
{ "matcher": { "id": "byName", "options": "Durée (s)" }, "properties": [ { "id": "unit", "value": "s" } ] }
] },
"options": { "showHeader": true, "sortBy": [ { "displayName": "Durée (s)", "desc": true } ] }
},
{
"type": "timeseries", "title": "Items collectés par étape (historique)", "id": 10,
"gridPos": { "h": 9, "w": 12, "x": 12, "y": 6 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_step_items > 0", "legendFormat": "{{step}}", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "custom": { "drawStyle": "bars", "fillOpacity": 40, "stacking": { "mode": "none" }, "lineWidth": 1 } }, "overrides": [] },
"options": { "legend": { "displayMode": "table", "placement": "right", "calcs": ["lastNotNull"] }, "tooltip": { "mode": "multi", "sort": "desc" } }
},
{
"type": "row", "title": "Modèle de données & scoring",
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 15 }, "id": 11, "collapsed": false
},
{
"type": "timeseries", "title": "Opportunités — missions A / cibles B", "id": 12,
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [
{ "refId": "A", "expr": "prospection_opportunities_total{kind=\"A\"}", "legendFormat": "Missions A", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } },
{ "refId": "B", "expr": "prospection_opportunities_total{kind=\"B\"}", "legendFormat": "Cibles B", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } }
],
"fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10, "lineWidth": 2, "pointSize": 5, "showPoints": "always" } }, "overrides": [] },
"options": { "legend": { "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "multi" } }
},
{
"type": "timeseries", "title": "Offres & entités collectées (historique)", "id": 13,
"gridPos": { "h": 8, "w": 8, "x": 12, "y": 16 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [
{ "refId": "A", "expr": "prospection_offers_total", "legendFormat": "Offres (missions)", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } },
{ "refId": "B", "expr": "prospection_entities_total", "legendFormat": "Entités (territoire)", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } },
{ "refId": "C", "expr": "prospection_scores_total", "legendFormat": "Offres scorées", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } }
],
"fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "fillOpacity": 10, "lineWidth": 2, "showPoints": "auto" } }, "overrides": [] },
"options": { "legend": { "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "multi" } }
},
{
"type": "bargauge", "title": "Modèle — dernier run", "id": 14,
"gridPos": { "h": 8, "w": 4, "x": 20, "y": 16 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [
{ "refId": "A", "expr": "prospection_signals_total", "legendFormat": "Signaux", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } },
{ "refId": "B", "expr": "prospection_entities_total", "legendFormat": "Entités", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } },
{ "refId": "C", "expr": "prospection_offers_total", "legendFormat": "Offres", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } },
{ "refId": "D", "expr": "prospection_scores_total", "legendFormat": "Scorées", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } }
],
"fieldConfig": { "defaults": { "thresholds": { "mode": "absolute", "steps": [ { "color": "blue", "value": null } ] } }, "overrides": [] },
"options": { "displayMode": "gradient", "orientation": "horizontal", "reduceOptions": { "calcs": ["lastNotNull"] }, "legend": { "showLegend": false } }
},
{
"type": "row", "title": "Livraison & alertes",
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 24 }, "id": 15, "collapsed": false
},
{
"type": "stat", "title": "Brief rendu", "id": 16,
"gridPos": { "h": 5, "w": 4, "x": 0, "y": 25 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_brief_rendered", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "mappings": [ { "type": "value", "options": { "0": { "text": "non", "color": "red", "index": 0 }, "1": { "text": "oui", "color": "green", "index": 1 } } } ], "thresholds": { "mode": "absolute", "steps": [ { "color": "red", "value": null }, { "color": "green", "value": 1 } ] } }, "overrides": [] },
"options": { "colorMode": "background", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Poussé sur Telegram", "id": 17,
"gridPos": { "h": 5, "w": 4, "x": 4, "y": 25 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_brief_telegram_pushed", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "mappings": [ { "type": "value", "options": { "0": { "text": "non", "color": "red", "index": 0 }, "1": { "text": "oui", "color": "green", "index": 1 } } } ], "thresholds": { "mode": "absolute", "steps": [ { "color": "red", "value": null }, { "color": "green", "value": 1 } ] } }, "overrides": [] },
"options": { "colorMode": "background", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Messages / mission", "id": 18,
"gridPos": { "h": 5, "w": 4, "x": 8, "y": 25 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_telegram_messages_sent", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "thresholds": { "mode": "absolute", "steps": [ { "color": "blue", "value": null } ] } }, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "area", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "stat", "title": "Vidéo brief", "id": 19,
"gridPos": { "h": 5, "w": 4, "x": 12, "y": 25 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "prospection_brief_video_kb * 1024", "instant": true, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"fieldConfig": { "defaults": { "unit": "bytes", "thresholds": { "mode": "absolute", "steps": [ { "color": "blue", "value": null } ] } }, "overrides": [] },
"options": { "colorMode": "value", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } }
},
{
"type": "table", "title": "Alertes prospection actives", "id": 20,
"gridPos": { "h": 5, "w": 8, "x": 16, "y": 25 },
"datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
"targets": [ { "refId": "A", "expr": "ALERTS{alertname=~\"Prospection.*\", alertstate=\"firing\"}", "instant": true, "format": "table", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" } } ],
"transformations": [
{ "id": "organize", "options": {
"excludeByName": { "Time": true, "Value": true, "__name__": true, "job": true, "instance": true, "alertstate": true },
"renameByName": { "alertname": "Alerte", "severity": "Sévérité" }
} }
],
"fieldConfig": { "defaults": { "custom": { "align": "auto" } }, "overrides": [] },
"options": { "showHeader": true, "footer": { "show": false } }
}
]
}
# default: # default:
# some-dashboard: # some-dashboard:
+53 -1
View File
@@ -1115,7 +1115,59 @@ prometheus: &prometheus_config
serverFiles: serverFiles:
## Alerts configuration ## Alerts configuration
## Ref: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ ## Ref: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
alerting_rules.yml: {} alerting_rules.yml:
groups:
# Pipeline prospection (métriques poussées au Pushgateway job=prospection en fin de
# run). NB : la LIVRAISON des alertes (Alertmanager → Telegram/…) n'est pas encore
# câblée dans ce cluster — ces règles s'évaluent et sont visibles dans Prometheus
# /alerts + le dashboard Grafana « Prospection » (panneau Alertes actives).
- name: prospection
rules:
- alert: ProspectionRunStale
expr: time() - prospection_run_timestamp_seconds > 90000 # > 25 h (cron quotidien)
for: 10m
labels:
severity: warning
app: prospection
annotations:
summary: "Prospection — aucun run réussi depuis plus de 25 h"
description: "Dernier run réussi il y a {{ $value | humanizeDuration }} ; le CronJob quotidien (~06:30 UTC) n'a pas abouti."
- alert: ProspectionRunFailed
expr: prospection_run_success == 0
for: 5m
labels:
severity: warning
app: prospection
annotations:
summary: "Prospection — le dernier run a échoué"
description: "prospection_run_success=0 : toutes les collectes ont échoué au dernier run."
- alert: ProspectionStepError
expr: prospection_step_status == 0
for: 5m
labels:
severity: info
app: prospection
annotations:
summary: "Prospection — étape {{ $labels.step }} en erreur"
description: "L'étape {{ $labels.step }} du pipeline a fini en erreur au dernier run."
- alert: ProspectionNoOffers
expr: prospection_offers_total == 0
for: 15m
labels:
severity: warning
app: prospection
annotations:
summary: "Prospection — 0 offre (mission) collectée"
description: "Aucune offre au dernier run : collecte France Travail / Free-Work potentiellement cassée."
- alert: ProspectionBriefNotSent
expr: prospection_brief_telegram_pushed == 0
for: 15m
labels:
severity: info
app: prospection
annotations:
summary: "Prospection — brief non poussé sur Telegram"
description: "Le brief vidéo n'a pas été diffusé sur Telegram au dernier run."
# groups: # groups:
# - name: Instances # - name: Instances
# rules: # rules: