Comment lire cette page. Dix étapes, un geste à la fois. Pour chacune : où cliquer, ce que Grafana affiche mot pour mot, et ce qu'il faut regarder. Les libellés de l'interface sont en anglais dans Grafana 13.2.2 (celui du kit) ; ils sont cités tels quels, en gras. Les chiffres seront différents chez toi ; les formes (nombre de séries, valeur du panneau, messages) doivent être les mêmes. Les blocs « Pour bien comprendre » sont facultatifs. Si le labo n'est pas démarré, retourne à la pratique guidée : la section En bref donne les commandes, kit compris (
https://github.com/hrhouma2/aiopsatlas-observabilite-labo-fr). Tout ce que tu crées ici est détruit à l'étape 10 : les trois tableaux de bord livrés avec le kit ne sont pas touchés.
Dans la pratique guidée, tu as tapé huit requêtes dans Explore et regardé trois tableaux de bord déjà faits. Tu sais donc lire Grafana. Mais si on te demande d'ajouter un chiffre sur un tableau, sais-tu par où commencer ? Ici, tu repars de zéro et tu assembles toi-même les trois objets de Grafana, du plus petit au plus grand : une source de données (Grafana ne stocke rien, il interroge Prometheus), un panneau (une requête plus une façon de la dessiner), un tableau de bord (des panneaux rangés sur une grille, avec un nom et une adresse). Une étape est un piège volontaire : tu casses une requête pour voir comment l'erreur de Prometheus traverse Grafana. À la fin, tu lis le JSON que Grafana a écrit pour toi et tu y retrouves les trois objets, puis tu supprimes tout.
Grafana est un cadre photo numérique. Il ne prend aucune photo : il va les chercher chez un photographe (la source de données : Prometheus, Loki) et les affiche. Chaque photo est un panneau : une question posée au photographe (la requête) et un format d'affichage (un chiffre, une courbe, une jauge). Le cadre lui-même, avec ses photos disposées sur une grille, c'est le tableau de bord : il a un nom, une adresse, et il est enregistré dans la base de Grafana sous la forme d'un document JSON.
| Grafana | Base SQL classique | Dans cet atelier |
|---|---|---|
| source de données (data source) | la connexion à la base | Prometheus (http://prometheus:9090) |
| requête (query) | SELECT … | count(up) |
| panneau (panel) | une vue enregistrée | Cibles surveillées |
| visualisation | la façon d'afficher le résultat | Stat (un grand chiffre) |
| tableau de bord (dashboard) | un rapport qui assemble plusieurs vues | Atelier M1 - Cibles Prometheus |
uid | clé primaire | adc947c (le tien sera différent) |
| JSON du tableau | le schéma exporté du rapport | étape 9 |
| dossier (folder) | schéma de la base | Dashboards (la racine) ; Labo observabilite pour les trois du kit |
Ouvre http://localhost:3000. Le menu principal est l'icône à trois traits en haut à gauche : il donne accès à Dashboards, Explore et Connections. Le fil d'Ariane en haut (par exemple Dashboards › New dashboard) dit toujours où tu es. Quand une action réussit, Grafana affiche pendant quelques secondes un bandeau en bas à droite (un toast) : Dashboard saved, Dashboard deleted. Quand une requête échoue, il affiche une boîte rouge sous le champ de requête, avec le message de Prometheus recopié tel quel.
Une fois le tableau enregistré, tu le reliras en JSON par l'API de Grafana. Dans PowerShell ou dans un terminal Linux, la même commande :
curl -s -u admin:aiopsatlas2026 http://localhost:3000/api/dashboards/uid/<uid><uid> est l'identifiant que Grafana a donné à ton tableau ; tu le liras dans l'adresse de la page à l'étape 8.
Menu principal → Connections → Data sources. Trois sources sont listées : Alertmanager, Loki et Prometheus (marquée default). Clique Prometheus. La page Settings s'ouvre, avec Prometheus server URL rempli : http://prometheus:9090. Ne change rien. Descends tout en bas et clique Save & test.
Successfully queried the Prometheus API.
Next, you can start to visualize data by building a dashboard from scratch or by querying data in the Explore view.À regarder : le bandeau vert. Grafana vient d'envoyer une requête à Prometheus et Prometheus a répondu. C'est le premier objet : une source de données, c'est une adresse et un type. L'adresse est http://prometheus:9090 et non http://localhost:9090 : Grafana tourne dans un conteneur, et depuis ce conteneur, Prometheus s'appelle prometheus. Ton navigateur, lui, l'atteint par localhost:9090. Deux noms pour la même machine, selon qui parle.
Toi, non. Le kit les décrit dans grafana/provisioning/datasources/sources.yml et Grafana les lit au démarrage : c'est le provisioning. Le fichier est court, ouvre-le : name: Prometheus, uid: prometheus, type: prometheus, url: http://prometheus:9090, isDefault: true. Sans ce fichier, la première chose à faire dans un Grafana neuf serait Add new data source, et tu taperais ces quatre lignes à la main. Le uid: prometheus te resservira à l'étape 9 : c'est par lui que ton panneau désignera sa source.
Menu principal → Explore. En haut, le sélecteur de source affiche Prometheus. À droite du champ, passe en Code (et non Builder). Tape :
uppuis Run query (ou Maj+Entrée).
up{instance="alertmanager:9093", job="alertmanager"}
up{instance="alloy:12345", job="alloy"}
up{instance="api:8000", job="api", service="api"}
up{instance="cadvisor:8080", job="cadvisor"}
up{instance="grafana:3000", job="grafana"}
up{instance="localhost:9090", job="prometheus"}
up{instance="loki:3100", job="loki"}
up{instance="node-exporter:9100", job="node-exporter"}À regarder : huit lignes dans la légende sous le graphique, les huit séries de l'étape 2 de l'atelier 1, dans l'ordre alphabétique de instance. La requête est exactement celle que tu as tapée dans Prometheus ; Grafana l'a transmise et a dessiné la réponse. Explore est un brouillon : rien n'y est enregistré, c'est là qu'on met une requête au point avant de la poser sur un panneau.
Toujours dans Explore, remplace la requête par une version fausse, exprès :
count(upRun query :
bad_data: invalid parameter "query": 1:9: parse error: unclosed left parenthesisÀ regarder : une boîte rouge sous le champ, et No data dans le graphique. Le message n'est pas de Grafana : parse error et la position 1:9 sont ceux de Prometheus, que tu as appris à lire dans l'atelier 1. Grafana préfixe seulement bad_data:, la catégorie d'erreur renvoyée par l'API de Prometheus. Règle : quand un panneau Grafana affiche une erreur PromQL, la corriger dans Prometheus d'abord (http://localhost:9090), puis recopier dans Grafana. Ferme la parenthèse, Run query : une seule ligne dans la légende, que Grafana nomme count(up) faute de labels (Prometheus, lui, écrivait {}), à 8. C'est la requête que tu vas poser sur ton panneau.
Menu principal → Dashboards. La page liste un seul dossier, Labo observabilite, qui contient les trois tableaux du kit. En haut à droite, New → New dashboard.
New dashboard
Add a panel to visualize your dataÀ regarder : le fil d'Ariane dit Dashboards › New dashboard, la page est vide, et le bouton Save est déjà là en haut à droite. Rien n'est encore enregistré : si tu fermes l'onglet maintenant, il ne reste rien. Un tableau de bord n'existe qu'à partir du moment où il est sauvegardé (étape 8). À droite, un panneau latéral Add propose Panel (« Drag or click to add a panel »).
Dans le panneau latéral Add, clique Panel. Un cadre apparaît sur la grille, titré New panel, avec le texte No visualization configured. À droite, le champ Title contient New panel : remplace-le par :
Cibles surveilléesÀ regarder : le titre du cadre change en direct. Tu as un panneau, mais il est vide : ni requête, ni visualisation. C'est le deuxième objet, réduit à son minimum : un emplacement sur la grille et un nom. Clique Edit visualization dans le panneau latéral : la page Edit panel s'ouvre, avec en bas l'onglet Queries 1 et, à droite, Suggestions / All visualizations.
Dans Queries, la ligne A est déjà reliée à Data source : Prometheus (la source par défaut). Passe en Code, tape dans le champ Enter a PromQL query… :
count(up)puis Run queries (ou Maj+Entrée).
Suggestions
Time series · Stat · Gauge · Bar gauge · Table · State timeline · Heatmap · HistogramÀ regarder : le volet de droite change : sous Suggestions, Grafana propose une dizaine de visualisations, et chaque vignette affiche déjà ta donnée : count(up) et 8. Le panneau du haut, lui, dit encore « Run a query to visualize it here or go to all visualizations » : il a la requête, il n'a pas encore choisi comment la dessiner. Requête et visualisation sont deux réglages séparés d'un même panneau.
Builder construit la requête avec des menus (choisir la métrique, ajouter un label, empiler une fonction). Code te laisse la taper. Les deux produisent la même chaîne PromQL, et tu peux passer de l'un à l'autre. Dans ce cours, on reste en Code : la requête que tu tapes ici est mot pour mot celle de Prometheus, et tu la retrouveras telle quelle dans le JSON de l'étape 9 ("editorMode": "code").
Dans Suggestions, clique la vignette Stat.
Stat
Value options
Calculate | All values
Calculation: Last *
Thresholds
80 (rouge)
Base (vert)À regarder : le panneau du haut affiche maintenant un grand 8 vert, avec la petite courbe de fond. Le volet de droite liste les options de Stat, dont deux à connaître : sous Value options, Calculate est coché et Calculation vaut Last * (le panneau montre la dernière valeur de la série, pas une moyenne) ; sous Thresholds, deux paliers, Base en vert et 80 en rouge : la valeur passerait au rouge à partir de 80. Ces seuils sont ceux que Grafana met par défaut sur tout nouveau panneau ; ils n'ont aucun sens pour un compte de cibles (tu verrais rouge à 80 cibles), tu les lirais et les changerais dans un vrai tableau. Ici, laisse-les : ce qui compte est de les reconnaître dans le JSON.
En haut à droite, Save. Le dialogue Save dashboard s'ouvre, avec deux onglets, Details et Changes 3, et trois champs : Title (New dashboard), Description, Folder (Dashboards).
À regarder d'abord : efface le titre et clique Save : le mot Required apparaît en rouge sous Title et le bouton Save se grise. Un tableau de bord a obligatoirement un nom. Tape :
Atelier M1 - Cibles PrometheusLe bouton se réactive. Clique Save.
Dashboard savedÀ regarder ensuite : le bandeau Dashboard saved, puis l'adresse de la page :
http://localhost:3000/d/adc947c/atelier-m1-cibles-prometheus?orgId=1&from=now-6h&to=now&timezone=browserTrois choses dans cette adresse. adc947c est le uid, tiré au hasard par Grafana : c'est l'identité du tableau, note-le. atelier-m1-cibles-prometheus est le titre mis en forme d'adresse ; il ne sert qu'à la lisibilité. from=now-6h&to=now est la période affichée, Last 6 hours par défaut pour un tableau neuf. Le crayon en haut à droite (Edit) a remplacé Save : tu es en lecture. Menu principal → Dashboards : ton tableau est dans la liste, à la racine, à côté du dossier Labo observabilite.
Avant de cliquer Save, ouvre Changes 3 : Grafana montre, en JSON, la différence entre un tableau neuf et celui que tu enregistres. Le chiffre est le nombre de modifications qu'il a comptées ; sur un tableau vide tout juste ouvert, l'onglet dit Changes 1. C'est la première fois que tu vois le JSON qui sera écrit ; l'étape 9 te le fait relire en entier.
Dans un terminal, avec ton uid à la place de adc947c :
curl -s -u admin:aiopsatlas2026 http://localhost:3000/api/dashboards/uid/adc947cLa réponse est un document JSON. Sa partie meta :
"meta": {
"slug": "atelier-m1-cibles-prometheus",
"url": "/d/adc947c/atelier-m1-cibles-prometheus",
"created": "2026-09-15T21:21:02Z",
"version": 1,
"folderTitle": "General"
}Et dans dashboard, le tableau panels contient un seul élément, ton panneau (raccourci aux champs qui comptent) :
{
"type": "stat",
"title": "Cibles surveillées",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"datasource": { "type": "prometheus", "uid": "prometheus" },
"editorMode": "code",
"expr": "count(up)",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"color": { "mode": "thresholds" },
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": 0 },
{ "color": "red", "value": 80 }
]
}
}
},
"options": {
"colorMode": "value",
"graphMode": "area",
"reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }
},
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
"id": 1,
"pluginVersion": "13.2.2"
}À regarder : les trois objets de l'atelier, écrits noir sur blanc. La source : "datasource": { "type": "prometheus", "uid": "prometheus" }, le uid du fichier de provisioning de l'étape 1. La requête : "expr": "count(up)", dans targets, avec "refId": "A" (la lettre de la ligne dans Queries) et "editorMode": "code". La visualisation : "type": "stat", et ses réglages de l'étape 7 : "calcs": ["lastNotNull"] est le Last * de l'écran, steps sont les deux Thresholds, green à la base et red à 80. gridPos dit où est le cadre sur la grille : en haut à gauche, 12 colonnes de large sur 24, 8 lignes de haut. Un tableau de bord Grafana n'est que ça : ce document, enregistré sous un uid. C'est ton livrable : ce bloc, avec stat, count(up) et prometheus entourés.
Sur la page du tableau, Edit (le crayon) → dans la barre latérale droite, Options (la roue) → View all settings → onglet JSON Model. C'est le même document, sans la partie meta, et tu peux le modifier là puis Save. C'est aussi ce document que le kit livre pour ses trois tableaux, dans grafana/provisioning/dashboards/*.json : ouvre api-catalogue.json et cherche "expr" : tu y liras des requêtes de la pratique guidée, exactement au format ci-dessus. Un tableau de bord se partage en envoyant ce fichier.
Sur la page du tableau, Edit → Options → View all settings. La page Settings s'ouvre (onglets General, Annotations, Variables, Links, Versions, Permissions, JSON Model). Tout en bas, le bouton rouge Delete dashboard.
Delete
Do you want to delete this dashboard?
Atelier M1 - Cibles Prometheus
Type "Delete" to confirmÀ regarder : le bouton Delete du dialogue est grisé tant que tu n'as pas tapé le mot Delete dans le champ. Tape-le, clique Delete.
Dashboard deleted
View deleted dashboardsGrafana te ramène à la page d'accueil. Preuve par l'API, avec ton uid :
curl -s -u admin:aiopsatlas2026 http://localhost:3000/api/dashboards/uid/adc947c{"message":"Dashboard not found"}Et la liste complète des tableaux de bord :
curl -s -u admin:aiopsatlas2026 "http://localhost:3000/api/search?type=dash-db"Trois entrées, les trois du kit, toutes dans le dossier Labo observabilite : api-catalogue (« API catalogue — signaux dorés »), hote-conteneurs (« Hôte et conteneurs »), journaux-api (« Journaux de l'API »). Le tien n'y est plus. Le dialogue de suppression le disait : Grafana garde les tableaux supprimés dans un historique jusqu'à douze mois (Recently deleted sur la page Dashboards), d'où ils peuvent être restaurés ; pour ce que tu fais dans ce cours, supprimé veut dire supprimé.
Reprends les dix gestes de mémoire, dans l'ordre, et coche :
Successfully queried the Prometheus API.up en mode Code rend 8 séries.count(up rend une boîte rouge bad_data: … parse error: unclosed left parenthesis ; count(up) rend {} et 8.count(up) puis Run queries remplit Suggestions avec la valeur 8 sur chaque vignette.8 ; Calculation vaut Last * ; Thresholds : Base vert, 80 rouge.Atelier M1 - Cibles Prometheus : bandeau Dashboard saved et un uid dans l'adresse.curl … /api/dashboards/uid/<uid> contient "type": "stat", "expr": "count(up)", "uid": "prometheus".curl rend {"message":"Dashboard not found"} et /api/search?type=dash-db liste exactement trois tableaux.Côté labo, rien n'a bougé : etat affiche toujours 10/10 services, 8/8 cibles up, 0 alertes actives. Grafana a écrit puis effacé une ligne dans sa propre base ; Prometheus n'a rien vu passer.
La page de connexion s'affiche et admin / admin est refusé. Le mot de passe du kit est aiopsatlas2026 (fixé dans docker-compose.yml, variable GF_SECURITY_ADMIN_PASSWORD). En ligne de commande, le même couple : -u admin:aiopsatlas2026 ; avec un mauvais mot de passe, l'API rend {"message":"Invalid username or password", …, "statusCode":401}.
Save & test rend une erreur au lieu du bandeau vert. Prometheus est arrêté ou en train de redémarrer : etat, puis attends que labo-prometheus soit healthy et réessaie. Si tu as changé l'URL par erreur, remets http://prometheus:9090 (pas localhost : depuis le conteneur Grafana, localhost c'est Grafana lui-même).
Explore rend No data sur up sans boîte rouge. Regarde le sélecteur de source en haut : tu es peut-être sur Loki (la pratique guidée t'y a laissé). Repasse sur Prometheus. Vérifie aussi la période en haut à droite : elle doit finir à now.
Le champ de requête refuse ce que je tape, ou le texte apparaît deux fois. Tu es en Builder : le champ libre n'existe qu'en Code. Bascule, efface, retape.
Le panneau reste sur « Run a query to visualize it here ». La requête est écrite mais n'a pas été lancée : Run queries ou Maj+Entrée. Si le volet Suggestions reste vide après ça, la requête a une erreur : la boîte rouge est sous le champ, descends.
Le Save du dialogue reste grisé, avec Required sous le titre. Le titre est vide. Tape-en un. Si tu as déjà enregistré un tableau du même nom à un essai précédent, Grafana l'accepte quand même : deux tableaux peuvent porter le même titre, ils ont des uid différents. Tu auras alors deux entrées dans la liste ; supprime celle en trop (étape 10).
Je ne retrouve pas le uid. Il est dans l'adresse, juste après /d/ : http://localhost:3000/d/adc947c/…. Sinon, curl -s -u admin:aiopsatlas2026 "http://localhost:3000/api/search?query=Atelier" rend le champ "uid" de chaque tableau dont le titre contient Atelier.
curl rend {"message":"Dashboard not found"} à l'étape 9 alors que le tableau est à l'écran. Le uid est mal recopié (majuscules, caractère en trop). Recopie-le depuis l'adresse.
J'ai supprimé un tableau du kit par erreur. Il est dans Dashboards → Recently deleted : restaure-le. Sinon, docker compose restart grafana : le provisioning relit grafana/provisioning/dashboards/ au démarrage et recrée les trois tableaux depuis leurs fichiers JSON (tableaux-de-bord.yml, updateIntervalSeconds: 30).
J'ai modifié un tableau du kit et Save refuse. Normal : allowUiUpdates: false dans tableaux-de-bord.yml. Les trois tableaux du kit se lisent, ne s'écrasent pas ; enregistre ta version sous un autre nom.