TP 9 — Wrapper Starlink HTTP + Grafana (monitorer du non-SNMP) · BROUILLON
Auteur : Thibaut Fontaine — Kodetis Institution : Université de la Réunion Date : 2026
Table des matières
Section intitulée « Table des matières »- Objectifs et contexte
- Glossaire express
- Section 0 — Pourquoi Starlink ne parle pas SNMP (15 min)
- Section 1 — Déployer le wrapper starlink-monitor (15 min)
- Section 2 — Inspecter l’API HTTP du wrapper (15 min)
- Section 3 — Configurer le scrape Prometheus (20 min)
- Section 4 — Premier panel Grafana en PromQL (15 min)
- Section 5 — Dashboard complet Starlink Concordia + DDU (25 min)
- Section 6 — Alerte sur obstruction prolongée (15 min)
- Section 7 — Comparaison SNMP vs HTTP/Prometheus (10 min)
- Synthèse finale (2 pts)
- Livrables & validation
1. Objectifs et contexte
Section intitulée « 1. Objectifs et contexte »📡 Poste SOC · La Réunion — Acte 1, Voir. Tu superviser déjà 4+4 équipements Concordia + DDU en SNMP (TP 6 + TP 7). Maintenant on ajoute le lien Starlink que IPEV a déployé pour la campagne d’été 2024-2025. Problème : Starlink ne parle pas SNMP.
🎯 Objectif métier — Tu apprends le pattern wrapper HTTP + Prometheus exporter qui s’applique à TOUS les équipements modernes propriétaires : Starlink, équipements IoT, API REST d’onduleurs récents, équipements télécoms 5G… Ce que tu apprends ici est transposable directement chez Orange Marine, Bouygues, EDF, etc.
🛰️ Le pivot Starlink dans les stations polaires
Section intitulée « 🛰️ Le pivot Starlink dans les stations polaires »Jusqu’en 2023, les stations TAAF (Concordia, DDU, Kerguelen, Crozet) utilisaient Inmarsat BGAN (492 kbps, latence 1.3 s) ou Iridium (lent mais polaire). Depuis 2024, Starlink polaire est déployé :
| Critère | Inmarsat BGAN | Iridium | Starlink |
|---|---|---|---|
| Latence vers PoP | ~1300 ms (GEO) | ~100 ms (LEO polaire) | ~30 ms (LEO méga-constellation) |
| Débit nominal | 492 kbps | 1.4 Mbps | ~200 Mbps |
| Coût/mois | très élevé | élevé | modéré |
| Souveraineté | UK / Viasat | US / Iridium | US / SpaceX |
| Protocole monitoring | SNMP standard | propriétaire | gRPC (port 9200) |
→ Concordia + DDU ont basculé. Mais le tooling de monitoring n’a pas suivi : Starlink expose ses métriques en gRPC, pas en SNMP. Si ton équipe attend que Zabbix sache parler gRPC, tu attendras longtemps.
🧰 La solution : pattern wrapper
Section intitulée « 🧰 La solution : pattern wrapper »┌──────────────────┐ gRPC ┌─────────────────┐ HTTP ┌────────────┐ PromQL ┌─────────┐│ Starlink Dishy │ ◄──────────│ starlink-monitor│ ◄───────────│ Prometheus │ ◄──────────│ Grafana ││ (port 9200) │ binaire │ (wrapper Bun) │ /metrics │ scrape 30s │ dashboard │ panels │└──────────────────┘ └─────────────────┘ └────────────┘ └─────────┘Le wrapper starlink-monitor :
- Parle gRPC au Dishy (ou simule, dans le lab)
- Expose les métriques en format Prometheus exporter (
/metrics) - Optionnellement : expose aussi une API REST JSON (
/dish/concordia/status) pour intégration custom
Ce que tu vas apprendre concrètement
Section intitulée « Ce que tu vas apprendre concrètement »- Pourquoi gRPC : binaire/typé, fait pour le streaming, mais incompatible avec Zabbix/SNMP
- Pattern exporter Prometheus : la convention
/metricsen text plain - Format Prometheus : metric naming, labels, types (gauge, counter, histogram)
- PromQL basique :
rate(),avg(),by (label), alerting - Architecture lab : ajouter un service au docker-compose existant
- Trade-off SNMP vs HTTP : quand l’un, quand l’autre
Architecture du TP
Section intitulée « Architecture du TP »graph LR subgraph "Lab Réunion (VM monitoring)" P[Prometheus
scrape 30s] G[Grafana
dashboards] P --> G end subgraph "Lab Concordia (VM concordia)" SM[starlink-monitor
:9100/metrics] DC[Dishy Concordia
simulé] SM -.gRPC sim.-> DC end subgraph "Lab DDU" SD[Dishy DDU
simulé] end P --HTTP scrape--> SM SM -.gRPC sim.-> SD
2. Glossaire express
Section intitulée « 2. Glossaire express »| Terme | Définition courte |
|---|---|
| gRPC | Google RPC — protocole binaire HTTP/2 + Protobuf, streaming bidirectionnel natif |
| Protobuf | Format de sérialisation binaire de Google (schéma .proto → code généré) |
| Exporter | Service qui collecte des métriques d’un système et les expose au format Prometheus |
/metrics | Endpoint conventionnel HTTP qui renvoie les métriques au format text |
| Scrape | Action de Prometheus qui poll un endpoint /metrics à intervalle régulier |
| Gauge | Métrique qui peut monter ET descendre (latence, température, état) |
| Counter | Métrique monotone croissante (octets transmis, requêtes traitées) |
| PromQL | Langage de query Prometheus — rate(metric[5m]), avg by (label)(...) |
| Label | Couple clé=valeur attaché à une métrique (site="concordia", pop="sydney-3") |
| Datasource | Dans Grafana, lien vers une source de données (Prometheus, Loki, Postgres…) |
3. Section 0 — Pourquoi Starlink ne parle pas SNMP (15 min)
Section intitulée « 3. Section 0 — Pourquoi Starlink ne parle pas SNMP (15 min) »3.1 SNMP : un protocole de 1988
Section intitulée « 3.1 SNMP : un protocole de 1988 »SNMP (Simple Network Management Protocol) est un standard IETF de 1988, conçu pour les équipements réseau de l’époque : switches, routeurs, imprimantes. Il s’appuie sur :
- UDP/161 : transport stateless
- OIDs : arbre numérique global (
1.3.6.1.2.1.1.1.0= sysDescr) - MIBs : schémas textuels qui décrivent les OIDs
- GET / GETNEXT / SET : opérations simples
C’est parfait pour des équipements à inventaire stable, basse cardinalité. Mais ça vieillit mal :
| Limite SNMP | Conséquence |
|---|---|
| Pas de streaming | Tu polles, tu attends N secondes, tu re-polles |
| Schéma figé via OIDs | Ajouter une métrique = négocier un nouveau PEN IANA |
| Pas de types modernes (struct, repeated) | Tableaux émulés via index .1, .2, … |
| Sécurité v3 ajoutée tardivement | La plupart des équipements restent en v2c |
| Authentification weak (community string) | “public” / “private” en clair encore courants |
3.2 gRPC : un protocole de 2015
Section intitulée « 3.2 gRPC : un protocole de 2015 »gRPC, sorti par Google en 2015, est conçu pour le microservices moderne :
- HTTP/2 : multiplexing, header compression, bidirectionnel
- Protobuf : sérialisation binaire ultra-compacte avec schéma typé
- Streaming : tu peux push N événements en flux continu
- Auth : TLS mutuel + JWT par défaut
Starlink (SpaceX) expose son Dishy en gRPC, port 9200, avec un service SpaceX.API.Device.dish dont la méthode principale est get_status qui retourne une struct DishGetStatusResponse :
message DishGetStatusResponse { DeviceInfo device_info = 1; DishState state = 2; float pop_ping_drop_rate = 3; float pop_ping_latency_ms = 4; float downlink_throughput_bps = 5; float uplink_throughput_bps = 6; ObstructionStats obstruction_stats = 7; float snr = 8; uint32 seconds_to_first_nonempty_slot = 9; uint32 alerts_bitfield = 10; // ... et ~60 autres champs}→ Tu vois immédiatement le problème : ces noms et ces types ne se mappent pas sur un OID SNMP. Tu ne peux pas demander à Zabbix de parler gRPC nativement.
3.3 Le pattern wrapper : solution canonique
Section intitulée « 3.3 Le pattern wrapper : solution canonique »Quand l’équipement parle un protocole moderne et que ton outil de monitoring parle un protocole legacy, tu mets un wrapper au milieu :
[équipement moderne] ──gRPC──> [wrapper] ──format compatible monitoring──> [Zabbix/Prom/...]Le wrapper a 3 responsabilités :
- Connecter à l’équipement via son protocole natif (gRPC, REST, MQTT, OPC-UA, Modbus…)
- Traduire les structures en métriques plat-typées
- Exposer sous un format que ton outil de monitoring sait lire
Tu peux exposer en :
- SNMP (rare, coûteux à coder)
- HTTP REST JSON (simple, ad-hoc)
- Prometheus
/metrics⭐ (standard de fait, ce qu’on fait dans ce TP) - StatsD / OpenMetrics / OTLP (alternatives modernes)
❓ Question d’évaluation 1 (1 pt · Niveau Standard)
Section intitulée « ❓ Question d’évaluation 1 (1 pt · Niveau Standard) »Cite 2 raisons techniques pour lesquelles SpaceX a choisi gRPC plutôt que SNMP pour le Dishy. Cite 1 conséquence opérationnelle pour les équipes ops qui veulent monitorer Starlink avec une stack existante (Zabbix, etc.).
4. Section 1 — Déployer le wrapper starlink-monitor (15 min)
Section intitulée « 4. Section 1 — Déployer le wrapper starlink-monitor (15 min) »4.1 Architecture du wrapper
Section intitulée « 4.1 Architecture du wrapper »Le service starlink-monitor (à ajouter dans zabbix-proxy-lab/docker-compose.yml) :
starlink-monitor: build: ./starlink-monitor image: zabbix-lab/starlink-monitor:dev container_name: starlink-monitor environment: MONITOR_PORT: "9100" SITES: "concordia,ddu" # En lab : on simule. En prod : pointe sur le Dishy réel. MODE: "simulator" DISHY_CONCORDIA: "192.168.100.1:9200" DISHY_DDU: "192.168.200.1:9200" ports: - "9100:9100" healthcheck: test: ["CMD-SHELL", "wget --spider -q http://localhost:9100/metrics || exit 1"] interval: 30s timeout: 5s retries: 3 restart: unless-stopped networks: [proxy-net]4.2 Démarrer
Section intitulée « 4.2 Démarrer »cd ~/zabbix-lab/zabbix-proxy-labdocker compose up -d starlink-monitordocker compose ps starlink-monitor# Doit afficher : Up X seconds (healthy)4.3 Vérifier que ça tourne
Section intitulée « 4.3 Vérifier que ça tourne »curl -s http://localhost:9100/metrics | head -30Tu dois voir un dump format Prometheus (voir section suivante).
5. Section 2 — Inspecter l’API HTTP du wrapper (15 min)
Section intitulée « 5. Section 2 — Inspecter l’API HTTP du wrapper (15 min) »5.1 Format Prometheus
Section intitulée « 5.1 Format Prometheus »Le wrapper expose 3 endpoints :
| Endpoint | Format | Usage |
|---|---|---|
/metrics | Prometheus text | Scrape par Prometheus |
/dish/:site/status | JSON | Inspection humaine / intégration ad-hoc |
/healthz | text | Healthcheck |
Exemple de sortie /metrics :
# HELP starlink_pop_ping_drop_rate Fraction of packets dropped to PoP (0.0-1.0)# TYPE starlink_pop_ping_drop_rate gaugestarlink_pop_ping_drop_rate{site="concordia"} 0.0starlink_pop_ping_drop_rate{site="ddu"} 0.0
# HELP starlink_pop_ping_latency_ms Round-trip latency to PoP in milliseconds# TYPE starlink_pop_ping_latency_ms gaugestarlink_pop_ping_latency_ms{site="concordia"} 32starlink_pop_ping_latency_ms{site="ddu"} 28
# HELP starlink_downlink_bps Downlink throughput in bits per second# TYPE starlink_downlink_bps gaugestarlink_downlink_bps{site="concordia"} 215000000starlink_downlink_bps{site="ddu"} 248000000
# HELP starlink_satellites_connected Number of satellites currently linked# TYPE starlink_satellites_connected gaugestarlink_satellites_connected{site="concordia"} 4starlink_satellites_connected{site="ddu"} 5
# HELP starlink_obstruction_fraction Fraction of sky obstructed (0.0-1.0)# TYPE starlink_obstruction_fraction gaugestarlink_obstruction_fraction{site="concordia"} 0.003starlink_obstruction_fraction{site="ddu"} 0.0015.2 Décortiquer une ligne
Section intitulée « 5.2 Décortiquer une ligne »starlink_pop_ping_latency_ms{site="concordia"} 32└──────────────┬───────────┘└────────┬───────┘ └┬┘ Nom de métrique Labels ValeurConventions Prometheus :
snake_casepour les noms- Suffix d’unité :
_ms,_bytes,_seconds,_total(pour les counters) - Labels : multi-valeurs (site, pop, alert_type) — créent les séries temporelles
5.3 JSON pour le debug humain
Section intitulée « 5.3 JSON pour le debug humain »curl -s http://localhost:9100/dish/concordia/status | jq .{ "site": "concordia", "deviceInfo": { "id": "ut01000000-XXXX-YYYY", "hardwareVersion": "rev4_proto2", "softwareVersion": "2026.05.0.mr59180" }, "state": "CONNECTED", "popPingDropRate": 0.0, "popPingLatencyMs": 32, "downlinkBps": 215000000, "uplinkBps": 28000000, "obstructionFraction": 0.003, "obstructionTimeSec": 842, "snr": 11.5, "satellitesConnected": 4, "alertsBitfield": 0, "pop": "sydney-pop-3"}❓ Question d’évaluation 2 (1 pt · Niveau Standard)
Section intitulée « ❓ Question d’évaluation 2 (1 pt · Niveau Standard) »En t’inspirant des conventions Prometheus, propose 2 nouveaux noms de métriques à exposer pour le Dishy, et justifie le choix de type (gauge vs counter) pour chacun.
6. Section 3 — Configurer le scrape Prometheus (20 min)
Section intitulée « 6. Section 3 — Configurer le scrape Prometheus (20 min) »6.1 Le job de scrape
Section intitulée « 6.1 Le job de scrape »Ouvre ~/monitoring/prometheus/prometheus.yml sur la VM monitoring et ajoute :
scrape_configs: # ... jobs existants (node-exporter, blackbox, etc.) ...
- job_name: 'starlink-monitor' scrape_interval: 30s scrape_timeout: 10s metrics_path: /metrics static_configs: - targets: ['<IP_CONCORDIA>:9100'] labels: environment: 'lab' location: 'concordia' team: 'taaf-ops'6.2 Recharger Prometheus
Section intitulée « 6.2 Recharger Prometheus »# Soit reload propre via API admincurl -X POST http://localhost:9090/-/reload
# Soit restart containerdocker restart prometheus6.3 Vérifier le scrape dans Prometheus UI
Section intitulée « 6.3 Vérifier le scrape dans Prometheus UI »Ouvre http://localhost:9090/targets — tu dois voir starlink-monitor en UP (vert).
Si rouge :
DOWN connection refused→ wrapper pas démarréDOWN timeout→ firewall entre VM monitoring et VM concordiaStatus: UP, Last Scrape: error→ format /metrics invalide (rare)
6.4 Première query PromQL
Section intitulée « 6.4 Première query PromQL »Dans http://localhost:9090/graph :
starlink_pop_ping_latency_msTu dois voir 2 séries (Concordia + DDU). Click “Graph” pour le voir dans le temps.
❓ Question d’évaluation 3 (2 pts · Niveau Avancé)
Section intitulée « ❓ Question d’évaluation 3 (2 pts · Niveau Avancé) »Écris 2 requêtes PromQL :
- La latence moyenne sur 5 minutes sur Concordia (utiliser
avg_over_time())- Le débit downlink en Mbps (pas en bps — convertis dans la requête)
7. Section 4 — Premier panel Grafana en PromQL (15 min)
Section intitulée « 7. Section 4 — Premier panel Grafana en PromQL (15 min) »7.1 Créer un dashboard
Section intitulée « 7.1 Créer un dashboard »Grafana → Dashboards → New → Add visualization → Datasource = Prometheus.
7.2 Panel “Latency POP”
Section intitulée « 7.2 Panel “Latency POP” »- Title :
Latence vers PoP par site - Query A :
starlink_pop_ping_latency_ms - Legend :
{{site}} - Visualization : Time series
- Unit :
Milliseconds (ms) - Thresholds :
40 = orange,100 = red
→ Tu obtiens 2 courbes : Concordia (~32 ms) et DDU (~28 ms).
7.3 Déclencher un événement
Section intitulée « 7.3 Déclencher un événement »Dans un autre terminal :
cd ~/zabbix-lab/zabbix-proxy-labmake starlink-concordia-obstructAttends 30 s (scrape interval). La courbe Concordia saute à 145 ms — tu visualises l’obstruction.
7.4 Rétablir
Section intitulée « 7.4 Rétablir »make starlink-concordia-restoreLa latence retombe à 32 ms.
8. Section 5 — Dashboard complet Starlink Concordia + DDU (25 min)
Section intitulée « 8. Section 5 — Dashboard complet Starlink Concordia + DDU (25 min) »Construis 6 panels :
| # | Panel | Query PromQL principale |
|---|---|---|
| 1 | Drop rate live (stat single value) | starlink_pop_ping_drop_rate * 100 |
| 2 | Latence PoP (time series) | starlink_pop_ping_latency_ms |
| 3 | Throughput downlink (time series) | starlink_downlink_bps / 1000000 (Mbps) |
| 4 | Throughput uplink (time series) | starlink_uplink_bps / 1000000 |
| 5 | Satellites connectés (stat) | starlink_satellites_connected |
| 6 | Obstruction du ciel (gauge) | starlink_obstruction_fraction * 1000 (en ‰) |
8.1 Variable de dashboard pour filtrer par site
Section intitulée « 8.1 Variable de dashboard pour filtrer par site »Settings → Variables → Add variable :
- Type : Query
- Name :
site - Query :
label_values(starlink_pop_ping_latency_ms, site) - Multi-value : ✅
- Include All : ✅
Puis dans chaque panel, change la query :
starlink_pop_ping_latency_ms{site=~"$site"}→ Tu obtiens un sélecteur en haut du dashboard pour filtrer Concordia / DDU / tous.
📸 Capture attendue
Section intitulée « 📸 Capture attendue »Inclure dans le rapport : capture du dashboard complet (6 panels) avec le selector
$sitequi sélectionneAll, en condition nominale (état post-make reset).
9. Section 6 — Alerte sur obstruction prolongée (15 min)
Section intitulée « 9. Section 6 — Alerte sur obstruction prolongée (15 min) »9.1 La règle métier
Section intitulée « 9.1 La règle métier »Si l’obstruction dépasse 5 % (50‰) pendant plus de 2 minutes, déclencher une alerte critique.
9.2 Configurer l’alerte Grafana
Section intitulée « 9.2 Configurer l’alerte Grafana »Panel “Obstruction du ciel” → onglet Alert → New alert rule :
- Query :
starlink_obstruction_fraction * 1000 - Reduce :
last - Condition :
IS ABOVE 50 - Evaluate every :
30sfor2m - Annotations :
- Summary :
Obstruction Starlink {{ $labels.site }} > 5% - Description :
Vérifier la dish (neige, glace, obstacle). Valeur actuelle : {{ $value }}‰
- Summary :
- Notification : channel Discord ou Google Chat (utiliser le webhook créé en TP 4)
9.3 Tester l’alerte
Section intitulée « 9.3 Tester l’alerte »make starlink-concordia-obstruct# Attendre 2 minutes ⏱️# → notif Discord arrivemake starlink-concordia-restore# → alert resolved arrive❓ Question d’évaluation 4 (2 pts · Niveau Avancé)
Section intitulée « ❓ Question d’évaluation 4 (2 pts · Niveau Avancé) »Pourquoi est-il dangereux de mettre
Evaluate every 30s for 30s(seuil franchi pour 30s seulement) ? Donne 1 scénario réel où ça génèrerait des faux positifs Starlink, et propose une condition mieux conçue.
10. Section 7 — Comparaison SNMP vs HTTP/Prometheus (10 min)
Section intitulée « 10. Section 7 — Comparaison SNMP vs HTTP/Prometheus (10 min) »10.1 Tableau récapitulatif
Section intitulée « 10.1 Tableau récapitulatif »| Critère | SNMP (TP 6/7) | HTTP/Prometheus (ce TP) |
|---|---|---|
| Modèle | Pull (poll) | Pull (scrape) |
| Transport | UDP/161 | HTTP/9100 |
| Schéma | Figé (OIDs + MIBs) | Flexible (labels) |
| Granularité | Une OID = une valeur | Une métrique + N labels |
| Découverte | Walk de l’arbre | up{} + service discovery |
| Authent | Community / v3 USM | mTLS / Bearer / IP allowlist |
| Streaming | ❌ | ❌ (pull, pas push) |
| Standard | IETF 1988 | De facto Prometheus 2015 |
| Adoption ICS/industriel | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| Adoption cloud/microservices | ⭐ | ⭐⭐⭐⭐⭐ |
10.2 Quand choisir quoi en 2026 ?
Section intitulée « 10.2 Quand choisir quoi en 2026 ? »| Situation | Outil |
|---|---|
| Switch / routeur / UPS classique | SNMP (templates existent) |
| Onduleur APC / Schneider | SNMP |
| Container / microservice maison | Prometheus |
| Équipement propriétaire récent (Starlink, IoT, 5G) | Prometheus via wrapper |
| Mix legacy + moderne | Hybride : SNMP côté Zabbix, Prom côté Grafana, corrélés |
❓ Question d’évaluation 5 (2 pts · Niveau Avancé)
Section intitulée « ❓ Question d’évaluation 5 (2 pts · Niveau Avancé) »Ton équipe te demande de monitorer un onduleur APC SmartUPS (existe en MIB SNMP standard) et un EV charger Schneider EVlink Pro AC (API REST JSON propriétaire). Quel outil pour chaque ? Justifie en 3 lignes par équipement.
11. Synthèse finale (2 pts)
Section intitulée « 11. Synthèse finale (2 pts) »Tu présentes ton dashboard et ton wrapper à un client industriel TAAF qui ne connaît pas Prometheus. En 5-7 lignes, vends-lui :
- Pourquoi tu n’as pas mis le Starlink dans Zabbix
- Comment ton wrapper se positionne entre l’équipement propriétaire et la stack de monitoring
- Quel est l’avantage opérationnel par rapport à attendre que Zabbix supporte gRPC
12. Livrables & validation
Section intitulée « 12. Livrables & validation »| # | Livrable | Forme |
|---|---|---|
| 1 | Wrapper starlink-monitor démarré et healthy | docker compose ps capture |
| 2 | Endpoint /metrics exposé | curl /metrics head 30 |
| 3 | Job Prometheus configuré | prometheus.yml extrait + capture targets UP |
| 4 | Dashboard Grafana 6 panels | export JSON + capture dashboard |
| 5 | Alerte obstruction configurée | screenshot règle + 1 notif Discord reçue |
| 6 | Réponses aux 5 questions d’évaluation | dans le rapport |
| 7 | Synthèse client TAAF | 5-7 lignes dans le rapport |
Évaluation : /20
- Q1 Standard · 1 pt
- Q2 Standard · 1 pt
- Q3 Avancé · 2 pts
- Q4 Avancé · 2 pts
- Q5 Avancé · 2 pts
- Wrapper opérationnel · 2 pts
- Prometheus scrape OK · 2 pts
- Dashboard 6 panels · 4 pts
- Alerte fonctionnelle · 2 pts
- Synthèse client · 2 pts
Annexes (à compléter)
Section intitulée « Annexes (à compléter) »- Annexe A : Code source du wrapper
starlink-monitor/server.tscommenté - Annexe B : Dashboard Grafana JSON pré-livré (à copier-coller pour étudiants en panne)
- Annexe C : Script Python d’inspection gRPC réel (pour étudiants curieux d’aller plus loin sur un vrai Dishy)
- Annexe D : Comparaison Prometheus exporter vs OpenTelemetry Collector (architecture moderne 2026)