Afficher les statistiques de la présidentielles 2022 sur Grafana avec Prometheus

Informatique 23 févr. 2022

Je sais pas vous, mais la présidentielle 2022 m'intéresse tellement pas cette année, c'est fade, sans gout, rien de fun et du racolage de bas étage... MAIS y a des données en opendata sur le site du conseil constitutionnel et qui dit données en opendata dit truc de geek à faire. C'est ce que j'ai fais.

⚠️
Attention, il vous faut déjà un Prometheus fonctionnel avec le node-exporter avec le textfile et un Grafana configuré

Tout d'abord vous constaterez qu'il y a un lien vers un fichier de données en json et grâce à la superbe commande de Bortzmeyer la majorité du travail est quasiment réalisé ;) .

De notre côté nous allons créer un script bash pour récupérer le json, le formater et écrire un fichier lisible par prometheus.

Il nous faut sur l'OS : curl et jq.

💡
Une bonne âme m'a transmis un script un peu différent et bien plus fonctionnel

D'une simple tâche planifié vous pouvez générer votre fichier Prometheus, c'est simple, rapide et indolore.

root@mul ~ # cat /etc/cron.d/prometheus-probe 
5 17 * * * root /usr/bin/curl -s https://presidentielle2022.conseil-constitutionnel.fr/telechargement/parrainagestotal.json | jq -rs '.[] | group_by(.Candidat)|map({"nom":.[0].Candidat, "parrainages": length})|.[]|"presidentielle{name=\"\(.nom)\", type=\"candidat\"} \(.parrainages)"' > /var/lib/prometheus/node-exporter/presidentielle.prom

Le fichier de résultat /var/lib/prometheus/node-exporter/presidentielle.prom se trouve dans le répertoire par défaut défini dans la configuration textfile de Prometheus.

Il ne vous reste plus qu'à vous occupez du dashboard Grafana (que vous trouverez un petit peu plus bas


Sinon vous pouvez utiliser la méthode ci dessous, tout aussi fonctionnelle :

#!/bin/bash

# On défini le fichier de résultat
result_file="/var/lib/prometheus/node-exporter/presidentielle.prom"

# On récupère la liste des présidentielles sans les trier (ça ne nous sert à rien)
list_candidat=$(curl -s https://presidentielle2022.conseil-constitutionnel.fr/telechargement/parrainagestotal.json | jq -rs '.[] | group_by(.Candidat) |map({"Candidat": .[0].Candidat, Nombre: length}) | .[] | @base64')
#Le base64 est la pour que la valeur passe la boucle for sans perdre des pièces (et donc rendre caduque le résultat)

# On défini une variable à 0 pour écraser le fichier de résultat à la prochaine execution
i=0
for candidat in ${list_candidat}
do
    #On récupère le candidat et le nombre de parainage
	name=$(echo ${candidat}  | base64 --decode | jq -r '.Candidat')
	parainage=$(echo ${candidat}  | base64 --decode | jq -r '.Nombre')
	if [ ${i} -eq 0 ]
	then
		echo "presidentielle{name=\"${name}\", type=\"candidat\"} ${parainage}" > ${result_file}
	else
		echo "presidentielle{name=\"${name}\", type=\"candidat\"} ${parainage}" >> ${result_file}
	fi
	((i++))
done

Le fichier de résultat /var/lib/prometheus/node-exporter/presidentielle.prom se trouve dans le répertoire par défaut défini dans la configuration textfile de Prometheus.

La forme presidentielle{name=\"${name}\", type=\"candidat\"} permet d'avoir tout les candidats dans la valeur presidentielle afin de mieux pouvoir filtrer.

Vous constaterez que, comparé à la commande de Bortzmeyer, j'ai remplacé le Candidat·e par Candidat c'est uniquement parce que le point median ne passait pas correctement dans le script (je n'ai pas creusé la raison).

Vous devez maintenant définir une tache cron à executer une fois ou deux par jours

Personnellement la mienne ressemble à ça

5 17 * * * dryusdan /bin/bash /home/dryusdan/presidentielle.sh

Il ne reste plus qu'à faire un dashboard. Vous n'avez plus qu'à importer le dashboard ci dessous :

{
  "__inputs": [
    {
      "name": "DS_PROMETHEUS",
      "label": "Prometheus",
      "description": "",
      "type": "datasource",
      "pluginId": "prometheus",
      "pluginName": "Prometheus"
    }
  ],
  "__elements": [],
  "__requires": [
    {
      "type": "panel",
      "id": "gauge",
      "name": "Gauge",
      "version": ""
    },
    {
      "type": "grafana",
      "id": "grafana",
      "name": "Grafana",
      "version": "8.4.1"
    },
    {
      "type": "datasource",
      "id": "prometheus",
      "name": "Prometheus",
      "version": "1.0.0"
    },
    {
      "type": "panel",
      "id": "timeseries",
      "name": "Time series",
      "version": ""
    }
  ],
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "target": {
          "limit": 100,
          "matchAny": false,
          "tags": [],
          "type": "dashboard"
        },
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "fiscalYearStartMonth": 0,
  "graphTooltip": 0,
  "id": null,
  "links": [],
  "liveNow": false,
  "panels": [
    {
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "mappings": [],
          "max": 100,
          "min": 0,
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 9,
        "w": 4,
        "x": 0,
        "y": 0
      },
      "id": 8,
      "options": {
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "lastNotNull"
          ],
          "fields": "",
          "values": false
        },
        "showThresholdLabels": false,
        "showThresholdMarkers": true
      },
      "pluginVersion": "8.4.1",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${DS_PROMETHEUS}"
          },
          "exemplar": true,
          "expr": "count(presidentielle{type=\"candidat\"})",
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "title": "Total candidat·e",
      "type": "gauge"
    },
    {
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "mappings": [],
          "max": 47,
          "min": 0,
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 9,
        "w": 4,
        "x": 4,
        "y": 0
      },
      "id": 11,
      "options": {
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "lastNotNull"
          ],
          "fields": "",
          "values": false
        },
        "showThresholdLabels": false,
        "showThresholdMarkers": true
      },
      "pluginVersion": "8.4.1",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${DS_PROMETHEUS}"
          },
          "exemplar": true,
          "expr": "count(presidentielle{type=\"candidat\"} >= 500)",
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "title": "Total candidat·e·s validé",
      "type": "gauge"
    },
    {
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "mappings": [],
          "max": 20000,
          "min": 0,
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 9,
        "w": 4,
        "x": 8,
        "y": 0
      },
      "id": 9,
      "options": {
        "orientation": "auto",
        "reduceOptions": {
          "calcs": [
            "lastNotNull"
          ],
          "fields": "",
          "values": false
        },
        "showThresholdLabels": false,
        "showThresholdMarkers": true
      },
      "pluginVersion": "8.4.1",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${DS_PROMETHEUS}"
          },
          "exemplar": true,
          "expr": "sum(presidentielle{type=\"candidat\"})",
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "title": "Total parrainages",
      "type": "gauge"
    },
    {
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 0,
            "gradientMode": "none",
            "hideFrom": {
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "auto",
            "spanNulls": false,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "displayName": "${__field.labels.name}",
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 14,
        "w": 12,
        "x": 12,
        "y": 0
      },
      "id": 2,
      "options": {
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom"
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${DS_PROMETHEUS}"
          },
          "exemplar": true,
          "expr": "presidentielle{type=\"candidat\"}",
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "title": "Présidentielle, parrainage des participant·e·s",
      "type": "timeseries"
    },
    {
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 0,
            "gradientMode": "none",
            "hideFrom": {
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "auto",
            "spanNulls": false,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "displayName": "${__field.labels.name}",
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 14,
        "w": 12,
        "x": 0,
        "y": 9
      },
      "id": 10,
      "options": {
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom"
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${DS_PROMETHEUS}"
          },
          "exemplar": true,
          "expr": "presidentielle{type=\"candidat\"} >= 500",
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "title": "Candidat·e·s validés",
      "type": "timeseries"
    },
    {
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 0,
            "gradientMode": "none",
            "hideFrom": {
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "auto",
            "spanNulls": false,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "displayName": "${__field.labels.name}",
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 9,
        "w": 12,
        "x": 12,
        "y": 14
      },
      "id": 4,
      "options": {
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom"
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${DS_PROMETHEUS}"
          },
          "exemplar": true,
          "expr": "presidentielle{type=\"total_parrain\"}",
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        },
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${DS_PROMETHEUS}"
          },
          "exemplar": true,
          "expr": "count(presidentielle{type=\"candidat\"} >= 500)",
          "hide": false,
          "interval": "",
          "legendFormat": "Candidats validé",
          "refId": "B"
        },
        {
          "datasource": {
            "type": "prometheus",
            "uid": "${DS_PROMETHEUS}"
          },
          "exemplar": true,
          "expr": "presidentielle{type=\"total_candidat\"}",
          "hide": false,
          "interval": "",
          "legendFormat": "",
          "refId": "C"
        }
      ],
      "title": "Total parrain",
      "type": "timeseries"
    }
  ],
  "refresh": "30m",
  "schemaVersion": 35,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": []
  },
  "time": {
    "from": "now-6h",
    "to": "now"
  },
  "timepicker": {},
  "timezone": "",
  "title": "Presidentielle 2022",
  "uid": "0juyiVfnz",
  "version": 6,
  "weekStart": ""
}

Sur ce, portez-vous bien.

Mots clés

Dryusdan

Chasseur de bug et régleur de problème (alias DevOps).