Grafana + Prometheus + Loki : Surveillez votre infrastructure comme un pro en 2026

Grafana + Prometheus + Loki : Surveillez votre infrastructure comme un pro en 2026

Introduction : Pourquoi avez-vous besoin d’une pile de surveillance ?

Tableau de bord Grafana Four Golden Signals — indicateurs de latence, de trafic et d'erreurs en temps réel
Tableau de bord Grafana affichant les données de surveillance en temps réel : latence (402 ms), trafic (279 000 opérations/s) et taux d’erreur pour l’ensemble des services.

On ne peut réparer ce qu'on ne voit pas. Que vous gériez un laboratoire personnel, un serveur de petite entreprise ou une infrastructure de production, naviguer à l'aveugle est la garantie de pannes qui durent des heures au lieu de quelques minutes. La suite Grafana + Prometheus + Loki — souvent appelée « GPLo » ou « Grafana LGTM » — est la norme du secteur pour la supervision d'infrastructures open source en 2026.

Voici le rôle de chaque composant :

  • Prometheus — Collecte et stocke des métriques chronologiques (CPU, mémoire, E/S disque, trafic réseau). Visualisez des données numériques au fil du temps.
  • Loki — Stocke et indexe les flux de journaux de vos serveurs et conteneurs. Similaire à Elasticsearch, mais plus léger et conçu pour Grafana.
  • Promtail — L'agent de transfert de journaux. Il suit vos fichiers journaux et les transfère à Loki.
  • Node Exporter — Expose les métriques matérielles et système d'exploitation de votre hôte Linux pour que Prometheus puisse les collecter.
  • Grafana — La couche de visualisation. De superbes tableaux de bord, des alertes et une interface utilisateur unifiée pour interroger Prometheus et Loki.

À la fin de ce guide, vous disposerez d'une pile de surveillance entièrement opérationnelle fonctionnant dans Docker, avec un tableau de bord Node Exporter professionnel, l'agrégation des journaux et une alerte CPU configurée.

Aperçu de l'architecture

┌─────────────────────────────────────────────────────────┐
│                     Your Linux Host                      │
│                                                         │
│  ┌──────────────┐    ┌──────────────┐                  │
│  │ Node Exporter│    │   Promtail   │                  │
│  │  :9100       │    │  (log agent) │                  │
│  └──────┬───────┘    └──────┬───────┘                  │
│         │ scrape            │ push logs                │
│         ▼                   ▼                          │
│  ┌──────────────┐    ┌──────────────┐                  │
│  │  Prometheus  │    │     Loki     │                  │
│  │   :9090      │    │    :3100     │                  │
│  └──────┬───────┘    └──────┬───────┘                  │
│         │                   │                          │
│         └─────────┬─────────┘                          │
│                   ▼                                    │
│           ┌──────────────┐                             │
│           │    Grafana   │                             │
│           │    :3000     │                             │
│           └──────────────┘                             │
└─────────────────────────────────────────────────────────┘

Prometheus collecte les métriques selon une planification. Loki reçoit les flux de journaux envoyés. Grafana se connecte aux deux comme sources de données et fournit l'interface unifiée pour les tableaux de bord et les alertes.

Prérequis

Infrastructure serveur surveillée par Prometheus
Infrastructure serveur surveillée par les exportateurs de nœuds Prometheus — collecte de métriques toutes les 15 secondes

Vous avez besoin d'un serveur Linux (Ubuntu 22.04/24.04 ou Debian 12) avec Docker et Docker Compose installés.

Installer Docker sur Ubuntu/Debian

# Install Docker using the official script
curl -fsSL https://get.docker.com | sudo sh

# Add your user to the docker group
sudo usermod -aG docker $USER
newgrp docker

# Verify installation
docker --version
docker compose version

Vous devriez voir Docker Engine 25.x ou une version plus récente et Docker Compose v2.x.

Structure du répertoire

Créez le répertoire du projet :

mkdir -p ~/monitoring/{prometheus,loki,promtail,grafana/provisioning}
cd ~/monitoring

Fichiers de configuration

prometheus.yml

cat > prometheus/prometheus.yml << 'EOF'
global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    monitor: 'homelab'

rule_files:
  # - "alert_rules.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node_exporter'
    static_configs:
      - targets: ['node-exporter:9100']
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        regex: '([^:]+).*'
        replacement: '${1}'

  - job_name: 'docker'
    static_configs:
      - targets: ['host.docker.internal:9323']
EOF

loki-config.yaml

cat > loki/loki-config.yaml << 'EOF'
auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096
  log_level: warn

common:
  instance_addr: 127.0.0.1
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

query_range:
  results_cache:
    cache:
      embedded_cache:
        enabled: true
        max_size_mb: 100

schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

ruler:
  alertmanager_url: http://localhost:9093

limits_config:
  reject_old_samples: true
  reject_old_samples_max_age: 168h
  ingestion_rate_mb: 16
  ingestion_burst_size_mb: 32

compactor:
  working_directory: /loki/compactor
  compaction_interval: 10m
  retention_enabled: true
  retention_delete_delay: 2h
  retention_delete_worker_count: 150
  delete_request_store: filesystem

chunk_store_config:
  chunk_cache_config:
    embedded_cache:
      enabled: true
      max_size_mb: 200

table_manager:
  retention_deletes_enabled: true
  retention_period: 720h
EOF

promtail-config.yaml

cat > promtail/promtail-config.yaml << 'EOF'
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: system
    static_configs:
      - targets:
          - localhost
        labels:
          job: varlogs
          host: monitoring-host
          __path__: /var/log/*log

  - job_name: containers
    static_configs:
      - targets:
          - localhost
        labels:
          job: docker
          host: monitoring-host
          __path__: /var/lib/docker/containers/*/*-json.log
    pipeline_stages:
      - json:
          expressions:
            output: log
            stream: stream
            attrs:
      - json:
          source: attrs
          expressions:
            tag:
      - regex:
          source: tag
          expression: '^(?P[^/]+)$'
      - labels:
          stream:
          container_name:
      - output:
          source: output
EOF

Le fichier docker-compose.yml complet

cat > docker-compose.yml << 'EOF'
services:

  prometheus:
    image: prom/prometheus:v2.51.2
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'
      - '--web.enable-admin-api'
    ports:
      - "9090:9090"
    networks:
      - monitoring

  grafana:
    image: grafana/grafana:11.0.0
    container_name: grafana
    restart: unless-stopped
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=changeme123
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_SERVER_DOMAIN=localhost
      - GF_SMTP_ENABLED=false
      - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
    ports:
      - "3000:3000"
    networks:
      - monitoring
    depends_on:
      - prometheus
      - loki

  loki:
    image: grafana/loki:3.0.0
    container_name: loki
    restart: unless-stopped
    volumes:
      - ./loki/loki-config.yaml:/etc/loki/local-config.yaml:ro
      - loki_data:/loki
    command: -config.file=/etc/loki/local-config.yaml
    ports:
      - "3100:3100"
    networks:
      - monitoring

  promtail:
    image: grafana/promtail:3.0.0
    container_name: promtail
    restart: unless-stopped
    volumes:
      - ./promtail/promtail-config.yaml:/etc/promtail/config.yml:ro
      - /var/log:/var/log:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
    command: -config.file=/etc/promtail/config.yml
    networks:
      - monitoring
    depends_on:
      - loki

  node-exporter:
    image: prom/node-exporter:v1.8.1
    container_name: node-exporter
    restart: unless-stopped
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.rootfs=/rootfs'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
    ports:
      - "9100:9100"
    networks:
      - monitoring

volumes:
  prometheus_data:
  grafana_data:
  loki_data:

networks:
  monitoring:
    driver: bridge
EOF

Démarrage de la pile

cd ~/monitoring
docker compose up -d

Regardez les conteneurs démarrer :

docker compose ps

Résultat attendu après environ 30 secondes :

NAME            IMAGE                           STATUS          PORTS
grafana         grafana/grafana:11.0.0          Up              0.0.0.0:3000->3000/tcp
loki            grafana/loki:3.0.0              Up              0.0.0.0:3100->3100/tcp
node-exporter   prom/node-exporter:v1.8.1       Up              0.0.0.0:9100->9100/tcp
prometheus      prom/prometheus:v2.51.2         Up              0.0.0.0:9090->9090/tcp
promtail        grafana/promtail:3.0.0          Up

Si un conteneur affiche « Redémarrage », consultez ses journaux :

docker compose logs prometheus
docker compose logs loki

Vérifiez que tout fonctionne

Vérifier les cibles Prometheus

Ouvrez http://SERVER_IP:9090/targets — vous devriez voir node_exporter et prometheus apparaître tous deux en vert.

Vérifier les métriques de Node Exporter

curl http://localhost:9100/metrics | head -20

Vous devriez voir des dizaines de lignes métriques commençant par node_cpu_seconds_total, node_memory_MemAvailable_bytes, etc.

Vérifier la disponibilité de Loki

curl http://localhost:3100/ready

Devrait renvoyer : ready

Configuration de Grafana

Accéder à Grafana

Ouvrez http://SERVER_IP:3000 dans votre navigateur. Connectez-vous avec admin / changeme123 (modifiez cela immédiatement en production !).

Ajouter une source de données Prometheus

  1. Cliquez sur Connexions → Sources de données → Ajouter une nouvelle source de données
  2. Sélectionnez Prometheus
  3. Définir l'URL sur http://prometheus:9090
  4. Laissez tout le reste par défaut
  5. Cliquez sur Enregistrer et tester — vous devriez voir « Interrogation de l'API Prometheus réussie »

Ajouter une source de données Loki

  1. Cliquez sur Connexions → Sources de données → Ajouter une nouvelle source de données
  2. Sélectionnez Loki
  3. Définir l'URL sur http://loki:3100
  4. Cliquez sur Enregistrer et tester — vous devriez voir « Source de données connectée et étiquettes trouvées »

Importer le tableau de bord complet de Node Exporter

Au lieu de créer un tableau de bord à partir de zéro, importez le tableau de bord Node Exporter le plus populaire de la communauté :

  1. Dans Grafana, cliquez sur Tableaux de bord → Importer
  2. Saisissez l'identifiant du tableau de bord : 1860
  3. Cliquez sur Charger
  4. Sélectionnez votre source de données Prometheus
  5. Cliquez sur Importer

Vous verrez instantanément un tableau de bord professionnel affichant l'utilisation du processeur, la mémoire, les E/S disque, le trafic réseau, l'utilisation du système de fichiers et bien plus encore, le tout à partir des données réelles de votre serveur.

Création d'une alerte CPU

Créons une alerte qui se déclenche lorsque l'utilisation du processeur reste supérieure à 80 % pendant 5 minutes :

  1. Dans Grafana, accédez à Alertes → Règles d'alerte → Nouvelle règle d'alerte
  2. Nommez-le : High CPU Usage
  3. Définir la source de données sur Prometheus
  4. Saisissez cette requête PromQL :
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
  1. Condition définie : EST AU-DESSUS DE 80
  2. Évaluation du jeu : évaluer chaque 1m, pour 5m (alerte déclenchée après 5 minutes consécutives au-dessus de 80 %).
  3. Dossier et groupe d'évaluation
  4. Ajouter des annotations : Résumé = CPU usage is {{ $value | printf "%.1f" }}% on {{ $labels.instance }}
  5. Cliquez sur « Enregistrer la règle et quitter ».

Pour recevoir des alertes par e-mail, Slack ou PagerDuty, configurez un point de contact sous Alertes → Points de contact .

Explorer les journaux avec Loki

Dans Grafana, accédez à Explorer et sélectionnez la source de données Loki. Utilisez LogQL pour interroger vos journaux :

# All system logs
{job="varlogs"}

# Filter for errors only
{job="varlogs"} |= "error" | logfmt

# SSH auth failures
{job="varlogs", filename="/var/log/auth.log"} |= "Failed password"

# Count error rate over time
rate({job="varlogs"} |= "error" [5m])

Proxy inverse Nginx pour Grafana

Au lieu d'exposer le port 3000, configurez Nginx comme proxy inverse afin que Grafana soit accessible à l'adresse https://grafana.yourdomain.com :

sudo apt install -y nginx certbot python3-certbot-nginx
sudo nano /etc/nginx/sites-available/grafana
server {
    listen 80;
    server_name grafana.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
sudo ln -s /etc/nginx/sites-available/grafana /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

# Get a free SSL certificate
sudo certbot --nginx -d grafana.yourdomain.com

Certbot configurera automatiquement le protocole HTTPS et mettra en place le renouvellement automatique du certificat.

Commandes Docker Compose utiles

# Stop the stack
docker compose down

# Stop and remove all data (careful!)
docker compose down -v

# Update all images
docker compose pull && docker compose up -d

# Restart a single service
docker compose restart grafana

# Follow logs of all services
docker compose logs -f

# Follow logs of a specific service
docker compose logs -f prometheus
Terminal d'agrégation de journaux Loki
Agrégation centralisée des journaux avec Loki — Requêtes LogQL sur l'ensemble de votre infrastructure en temps réel

Conclusion

Vous disposez désormais d'une infrastructure de supervision de niveau production, déployée sur votre propre infrastructure. Prometheus assure la collecte des métriques avec une conservation de 30 jours. Loki agrège tous vos journaux. Grafana centralise le tout grâce à des tableaux de bord intuitifs et des alertes intelligentes.

Cette pile évolue bien au-delà d'un seul serveur : ajoutez plus de cibles de récupération dans prometheus.yml, ajoutez plus d'instances Promtail sur d'autres machines pointant vers le même Loki, et vos tableaux de bord acquièrent automatiquement de nouvelles données.

Quelques idées pour étendre cette configuration :

  • Ajouter cAdvisor pour surveiller les conteneurs Docker individuels (gcr.io/cadvisor/cadvisor:latest, port 8080)
  • Ajoutez Alertmanager pour acheminer les alertes vers Slack, PagerDuty ou par e-mail.
  • Ajoutez Blackbox Exporter pour surveiller les points de terminaison HTTP/HTTPS depuis l'extérieur.
  • Configurez le provisionnement Grafana pour déployer automatiquement les tableaux de bord et les sources de données sous forme de code.
  • Intégrer Tempo pour le traçage distribué (la pile LGTM complète)

Pour les administrateurs système sérieux, l'observabilité est essentielle. Grâce à cette architecture, vous serez informé des problèmes avant même vos utilisateurs — et c'est précisément l'objectif recherché.