📊 Grafana – Dashboards, Monitoring & Observabilité
Guide complet IDEO‑Lab sur l'outil de visualisation (Prometheus, Loki, Alerting).
Vue d'ensemble
Visualisation, Observabilité, Agnostique.
Dashboards MonitoringArchitecture
Data Sources, Panels, Dashboards.
Data Source PanelsInstallation Linux
apt (Debian/Ubuntu) & dnf (RHEL/Rocky).
Installation Docker
docker run (persistance), docker-compose.
Configuration (grafana.ini)
grafana.ini, variables d'env (GF_).
Data Sources (UI & YAML)
Prometheus, Loki, Postgres, InfluxDB.
Prometheus LokiPanels (Visualisation)
Time series, Stat, Gauge, Table, Bar chart.
Time Series StatQuery Editor (PromQL)
rate(), sum(), by (job), Legend.
Variables (Dynamisme)
$variable, Query, Custom, label_values().
Query (LogQL - Loki)
{app="..."} |= "erreur", rate(), json.
Alerting (Unified)
Alert Rules, Contact Points (Alertmanager).
Alerting AlertmanagerProvisioning (YAML)
Data Sources (datasource.yml) & Dashboards (dashboard.yml).
Stack "GLT" (Loki/Tempo)
Prometheus (Metrics), Loki (Logs), Tempo (Traces).
Metrics Logs TracesCheat-sheet PromQL
rate, sum by, topk, histogram_quantile.
Qu'est-ce que Grafana ?
Grafana est une plateforme open-source d'analyse et de visualisation de métriques. C'est l'outil de *facto* pour créer des dashboards de monitoring complexes et interactifs.
Sa force principale est d'être "agnostique" : il peut se connecter à des dizaines de sources de données (Data Sources) différentes et les agréger sur un seul dashboard.
Les 3 piliers de l'Observabilité
Grafana est au centre de l'observabilité moderne :
- MÉTRIQUES (Metrics) : (Le "Quoi" - ex: CPU à 80%). Source : Prometheus, InfluxDB.
- LOGS (Logs) : (Le "Pourquoi" - ex: "Error: DB timeout"). Source : Loki, Elasticsearch.
- TRACES (Tracing) : (Le "Où" - ex: "Le timeout vient de l'API /auth"). Source : Tempo, Jaeger.
Grafana vs. Kibana
C'est une confusion fréquente.
| Critère | Grafana | Kibana (de Elastic) |
|---|---|---|
| Foyer | Agnostique (Multi-sources) | ELK-Centric (Fait pour Elasticsearch) |
| Force (Métriques) | Exceptionnel (PromQL) | Moyen (MetricsBeat) |
| Force (Logs) | Bon (avec Loki/LogQL) | Exceptionnel (Elasticsearch) |
| Alerting | Excellent (Unified Alerting) | Intégré mais lié à ELK. |
| Usage | Monitoring DevOps, SRE, Métriques. | Analyse de Logs, Sécurité (SIEM). |
Les 3 Blocs de Grafana
- Data Source (Source de Données) : La "base de données" où sont stockées les métriques ou les logs (ex: Prometheus, Loki, PostgreSQL...). Grafana *ne stocke* aucune donnée.
- Panel (Panneau) : L'unité de visualisation. C'est un graphique (ex: "Time series", "Stat", "Gauge"). Un panel est lié à une ou plusieurs requêtes sur une Data Source.
- Dashboard (Tableau de bord) : Une collection de Panels, organisés en lignes et colonnes. C'est ce que l'utilisateur consulte.
Schéma de flux
+-----------------+
| Prometheus |--+
| (Metrics) | |
+-----------------+ | (1. Data Sources)
| Loki (Logs) |--+
+-----------------+ |
| Postgres (SQL) |--+
+-----------------+ |
|
▼
+------------------------------------+
| Serveur GRAFANA (Frontend + Backend) |
| (Stocke Dashboards, Gère les Users) |
| |
| +--------------------------------+ |
| | Dashboard: "Mon App" | |
| | +----------+ +----------+ | |
| | | Panel 1 | | Panel 2 | | | (2. Panels)
| | | (Query A) | | (Query B) | | |
| | +----------+ +----------+ | |
| +--------------------------------+ |
+------------------------------------+
|
▼
+------------------------------------+
| Utilisateur (Navigateur Web) |
+------------------------------------+Ubuntu / Debian (Dépôt officiel)
# 1. Installer les prérequis sudo apt-get install -y apt-transport-https software-properties-common wget # 2. Ajouter la clé GPG sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key # 3. Ajouter le dépôt echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list # 4. Installer sudo apt-get update sudo apt-get install -y grafana
RHEL / Rocky / Fedora (Dépôt officiel)
# 1. Créer le fichier .repo sudo vi /etc/yum.repos.d/grafana.repo # Coller ceci dans le fichier : [grafana] name=grafana baseurl=https://packages.grafana.com/oss/rpm repo_gpgcheck=1 gpgkey=https://packages.grafana.com/gpg.key enabled=1 gpgcheck=1 # 2. Installer sudo dnf install -y grafana
Post-Installation (systemd)
# Recharger le daemon (après install) sudo systemctl daemon-reload # Activer au démarrage sudo systemctl enable grafana-server # Démarrer le service sudo systemctl start grafana-server # Vérifier le statut sudo systemctl status grafana-server
Une fois démarré, Grafana est accessible sur http://[IP_SERVEUR]:3000.
Login/pass par défaut : admin / admin (vous devrez le changer).
N'oubliez pas d'ouvrir le port 3000 dans votre firewall (firewalld ou ufw).
docker run (Simple)
Pour un test rapide, avec persistance des données (dashboards, config) via un volume Docker.
docker run -d \
--name=grafana \
-p 3000:3000 \
-v grafana-data:/var/lib/grafana \
grafana/grafana-oss:latest
# -p 3000:3000 : Lie le port 3000
# -v grafana-data:/var/lib/grafana : Volume pour les données
# grafana/grafana-oss : Version Open SourceAccès : http://localhost:3000 (admin/admin).
docker-compose.yml (Stack Grafana + Prometheus)
La méthode recommandée pour le dev, car elle lance Grafana ET sa source de données (Prometheus).
version: '3.8'
services:
grafana:
image: grafana/grafana-oss:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
# (Pas besoin de depends_on, Grafana gère la reconnexion)
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
volumes:
grafana-data:Lancez docker compose up -d.
Grafana : http://localhost:3000
Prometheus : http://localhost:9090
(Dans Grafana, ajoutez une source Prometheus avec l'URL : http://prometheus:9090)
grafana.ini
Le fichier de configuration principal.
Emplacement : /etc/grafana/grafana.ini (Linux) ou /usr/share/grafana/conf/defaults.ini (Docker).
Toute modification nécessite un redémarrage (sudo systemctl restart grafana-server).
Exemples (grafana.ini)
[server] # Port HTTP http_port = 3000 # Adresse d'écoute http_addr = 0.0.0.0 # URL racine (si derrière reverse proxy) # root_url = https://grafana.ideolab.com [security] # Mot de passe 'admin' (obsolète, à changer au 1er login) ;admin_user = admin ;admin_password = admin # Autoriser l'intégration (iframe) allow_embedding = true [auth.anonymous] # Autoriser les dashboards publics enabled = true org_name = IDEO-Lab Public org_role = Viewer
Variables d'Environnement (Docker)
Pour Docker, il est plus simple de configurer via des variables d'environnement GF_.
Format : GF_[SECTION]_[CLE] (majuscules).
docker run -d -p 3000:3000 \ -e "GF_SECURITY_ADMIN_USER=admin_ideo" \ -e "GF_SECURITY_ADMIN_PASSWORD=mon_pass_secret" \ -e "GF_AUTH_ANONYMOUS_ENABLED=true" \ grafana/grafana-oss
Configuration (Interface UI)
- Allez dans Connections (Icône 🔌) -> Data sources.
- Cliquez "Add data source".
- Sélectionnez le type (ex: Prometheus).
Exemple : Prometheus
- Name :
Mon-Prometheus - URL :
http://localhost:9090(ouhttp://prometheus:9090si Docker) - Access :
Server (default) - Cliquez "Save & Test".
Exemple : Loki
- Name :
Mon-Loki - URL :
http://localhost:3100(ouhttp://loki:3100) - Cliquez "Save & Test".
Provisioning (Dashboards as Code)
La méthode de production. On définit les sources dans un .yml que Grafana lit au démarrage.
Créez /etc/grafana/provisioning/datasources/prometheus.yml :
# apiVersion 1 (obligatoire)
apiVersion: 1
# Liste des data sources
datasources:
- name: Prometheus-Prod
type: prometheus
access: proxy # (Server)
url: http://prometheus.prod.internal:9090
isDefault: true
editable: false # (Empêche la modif UI)
- name: Loki-Prod
type: loki
access: proxy
url: http://loki.prod.internal:3100
- name: Grafana (pour les tests)
type: grafana
access: proxy
url: http://localhost:3000Les Panels Incontournables
| Panel | Description |
|---|---|
| Time series | Le standard. Graphe Ligne (Temps vs Valeur). Idéal pour le CPU, la RAM, les requêtes/sec. |
| Stat | Affiche une seule grosse valeur (ex: CPU Actuel, Total Utilisateurs). Peut changer de couleur (Thresholds). |
| Gauge | Une jauge semi-circulaire (0-100%). Idéal pour les pourcentages (Disque, RAM). |
| Bar chart | Graphe à barres (horizontal ou vertical). |
| Table | Affichage tabulaire (ex: liste de processus, résultats SQL). |
| Logs | Panel dédié à Loki/Elasticsearch pour afficher les lignes de log. |
Un dashboard est un assemblage de panels, organisés en "Rows" (Lignes).
L'éditeur de requête
C'est le cœur du Panel. C'est ici que l'on écrit la requête (ex: PromQL) pour récupérer les données.
Éléments clés :
- Data source : (Choisir "Prometheus-Prod").
- Query Editor (A) : La zone de texte pour la requête.
- Legend : Formatage de la légende (ex:
{{}}job}}}}). - Min step : Intervalle de "scrape" (ex:
15s). - Options : Type de graphe, style...
PromQL : Les requêtes de base
PromQL (Prometheus Query Language) est un langage fonctionnel pour les séries temporelles.
% 1. Métrique simple (Gauge)
# CPU (en %) par instance (job 'node')
node_cpu_usage_percentage{job="node"}
% 2. Taux de requêtes (Counter -> Gauge)
# (Le "Hello World" de PromQL)
# Requêtes/sec, moyennées sur 5 min
rate(http_requests_total[5m])
% 3. Agrégation (sum)
# Total des req/sec, groupées par 'job' (API)
sum(rate(http_requests_total[5m])) by (job)
% 4. Top 5
# Top 5 des processus utilisant le plus de RAM
topk(5, process_resident_memory_bytes)Rendre les Dashboards Interactifs
Les "Variables" sont la fonctionnalité la plus puissante de Grafana. Elles créent des **menus déroulants** en haut du dashboard.
Quand l'utilisateur change la valeur du menu (ex: "Job: api-prod"), toutes les requêtes du dashboard qui utilisent cette variable ($job) sont rechargées.
Exemple ($job)
Dashboard: "Mon Infrastructure"
[ Job: [api-prod ▼] ] [ Instance: [api-01 ▼] ]
+------------------------------------------+
| CPU (Query: node_cpu{job="$job", ...}) |
+------------------------------------------+
| RAM (Query: node_ram{job="$job", ...}) |
+------------------------------------------+
Création (Dashboard Settings > Variables > New)
Type : Query
La variable est remplie par le résultat d'une requête (ex: PromQL).
| Champ | Exemple (Variable $job) |
|---|---|
| Name | job |
| Type | Query |
| Data source | Prometheus |
| Query | label_values(up, job) (PromQL : donne tous les "job") |
| Selection Options | Cocher "Multi-value" et "Include All option" |
Utilisation dans un Panel
# Utiliser la variable $job
# Si 'All' est sélectionné, $job vaut "api|db|..."
# L'opérateur '=~' (Regex) est requis pour 'All'
node_cpu_usage_percentage{job=~"$job"}Alerting (Post-Grafana 8)
Grafana intègre un système d'alerting complet (basé sur le moteur de Prometheus Alertmanager).
Flux de travail :
- Contact Points (Où) : Définir les "cibles" (Email, Slack, Teams, PagerDuty...).
- Notification Policies (Quand) : Définir "comment" router (ex: les "critical" vont sur PagerDuty, les "info" sur Slack).
- Alert Rules (Quoi) : Définir la condition (ex: "CPU > 80% pendant 5 min").
Créer une "Alert Rule"
La méthode la plus simple est de créer une règle depuis un Panel :
1. Créer un Panel (ex: CPU) 2. Clic Droit -> Edit 3. Onglet "Alert" -> "Create alert rule from this panel" 4. (Grafana copie la requête A) 5. Ajouter une requête "B" (Reduce) - Input: A - Mode: "Reduce" -> "Last" (dernière valeur) 6. Ajouter une requête "C" (Threshold) - Input: B - Condition: "IS ABOVE 80" 7. Définir le "Folder" et le "Group" 8. Définir "For" (Durée) -> "5m" (L'alerte ne se déclenche que si C est VRAI pendant 5 min)
"Grafana as Code"
Configurer des Data Sources et créer des Dashboards via l'UI est simple, mais non-reproductible (et risqué).
Le Provisioning permet de définir les Data Sources et les Dashboards dans des fichiers (.yml, .json) que Grafana lit au démarrage.
Avantages :
- Stocké dans Git (Versionning, backup).
- Reproductible (Dev/Staging/Prod).
- Déploiement (CI/CD).
Emplacement (Linux) : /etc/grafana/provisioning/
/etc/grafana/provisioning/datasources/default.yml
apiVersion: 1
# (cf 2.2)
datasources:
- name: Prometheus-Prod
type: prometheus
access: proxy
url: http://prometheus.prod.internal:9090
isDefault: true
editable: false/etc/grafana/provisioning/dashboards/default.yml
Ce .yml "pointe" vers un dossier contenant les .json des dashboards.
apiVersion: 1
providers:
- name: 'Default' # Nom du provider
orgId: 1
folder: '' # (Dossier racine Grafana)
type: file
options:
# Chemin où Grafana va chercher les JSON
path: /var/lib/grafana/dashboards
# (ou /etc/grafana/dashboards/)Le Dashboard (.json)
Vous ne l'écrivez pas à la main !
1. Créez votre dashboard dans l'UI.
2. Allez dans "Dashboard settings" (Icône ⚙️) -> "JSON Model".
3. Copiez/Collez ce JSON dans un fichier (ex: /var/lib/grafana/dashboards/mon_dashboard.json).
La Stack "GLT" (Grafana/Loki/Tempo)
Grafana Labs pousse sa propre stack d'observabilité (alternative à ELK) :
1. Prometheus (ou Mimir) - Metrics
Prometheus (standard CNCF) reste le roi des métriques.
2. Loki - Logs
"Prometheus, but for logs". Loki est un système d'agrégation de logs. Il ne fait pas d'indexation full-text (comme Elastic). Il n'indexe que les *labels* (métadonnées : job, app, level).
Avantage : Extrêmement léger et peu coûteux.
Requête (LogQL) : {job="api"} |= "error"
3. Tempo - Traces
Un système de "Distributed Tracing" (comme Jaeger). Il suit une requête à travers plusieurs microservices.
Le "Workflow" d'Observabilité
La puissance de Grafana est de lier ces sources :
1. [Dashboard "Metrics" (Prometheus)]
(CPU élevé, Taux d'erreur 500 en hausse)
|
| (Clic sur le graphe -> "Voir les logs liés")
|
▼
2. [Dashboard "Logs" (Loki)]
(Filtre auto: {job="api", status="500"})
(Log: "Error: TraceID=abc123 ...")
|
| (Clic sur le TraceID)
|
▼
3. [Dashboard "Traces" (Tempo)]
(Affiche la cascade de la requête "abc123")
- API-Gateway (5ms)
- AuthService (10ms)
- DB-Service (500ms) <-- (Le coupable !)Types de Métriques
- Gauge : (Valeur instantanée : RAM, CPU).
- Counter : (Compteur qui n'augmente jamais : req_total, errors_total). Doit *toujours* être utilisé avec
rate().
Fonctions Clés (Counters)
# Req/sec (moyenne sur 5m) rate(http_requests_total[5m]) # Augmentation (sur 1h) increase(http_requests_total[1h])
Agrégation (sum, avg)
# Total des req/sec, par job et path sum(rate(http_requests_total[5m])) by (job, path) # CPU moyen par instance avg(node_cpu_usage_percentage) by (instance) # Top 5 des process par RAM topk(5, process_resident_memory_bytes) # 95ème centile (Histogrammes) histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le) )
