27 KiB
Ecris moi le fichier de config pour Loki avec le stockage des donnée dans s3 Minio server ChatGPT a dit : Voici un exemple complet de fichier de configuration pour Loki (loki-config.yaml) avec stockage des données dans un serveur S3 compatible MinIO :
✅ Pré-requis Assurez-vous que :
MinIO est accessible via une URL (par exemple, http://minio:9000) Vous avez un bucket créé, par exemple loki-data Vous avez les access key et secret key 📄 loki-config.yaml auth_enabled: false
server: http_listen_port: 3100 grpc_listen_port: 9095 log_level: info
ingester: lifecycler: ring: kvstore: store: inmemory replication_factor: 1 chunk_idle_period: 5m chunk_retain_period: 30s max_transfer_retries: 0
schema_config: configs: - from: 2022-01-01 store: boltdb-shipper object_store: s3 schema: v11 index: prefix: index_ period: 24h
storage_config: boltdb_shipper: active_index_directory: /loki/index cache_location: /loki/index_cache shared_store: s3
aws: s3: http://minio:9000/loki-data bucketnames: loki-data endpoint: minio:9000 access_key_id: minioadmin secret_access_key: minioadmin insecure: true # Important si MinIO ne supporte pas HTTPS s3forcepathstyle: true
compactor: working_directory: /loki/compactor shared_store: s3
limits_config: reject_old_samples: true reject_old_samples_max_age: 168h
chunk_store_config: max_look_back_period: 0s
table_manager: retention_deletes_enabled: true retention_period: 336h # 14 jours
ruler: storage: type: local local: directory: /loki/rules rule_path: /loki/rules-temp alertmanager_url: http://localhost:9093 ring: kvstore: store: inmemory enable_api: true 📁 Volumes Docker (si vous utilisez un conteneur Loki) Si vous utilisez Loki avec Docker ou Kubernetes, montez les volumes nécessaires :
volumes:
- ./loki-data:/loki 🧪 Test de connectivité MinIO Avant de démarrer Loki, vous pouvez tester les accès S3 avec un outil comme mc (MinIO client) :
mc alias set localminio http://minio:9000 minioadmin minioadmin mc ls localminio/loki-data Souhaitez-vous également un exemple de docker-compose avec Grafana, Loki, Promtail et MinIO ?
Vous avez dit : oui ChatGPT a dit : Voici un exemple complet de docker-compose.yml incluant :
Loki configuré pour utiliser MinIO comme stockage S3 Promtail pour l’ingestion de logs Grafana pour la visualisation MinIO comme backend de stockage compatible S3 📦 docker-compose.yml
version: '3.8'
services:
minio: image: minio/minio:latest container_name: minio ports: - "9000:9000" - "9001:9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin command: server /data --console-address ":9001" volumes: - ./minio-data:/data
create-bucket: image: minio/mc depends_on: - minio entrypoint: > /bin/sh -c " sleep 5; mc alias set local http://minio:9000 minioadmin minioadmin; mc mb -p local/loki-data; exit 0; "
loki: image: grafana/loki:latest container_name: loki ports: - "3100:3100" volumes: - ./loki-config.yaml:/etc/loki/loki-config.yaml - ./loki-data:/loki command: -config.file=/etc/loki/loki-config.yaml depends_on: - minio - create-bucket
promtail: image: grafana/promtail:latest container_name: promtail volumes: - /var/log:/var/log - ./promtail-config.yaml:/etc/promtail/promtail.yaml command: -config.file=/etc/promtail/promtail.yaml depends_on: - loki
grafana: image: grafana/grafana:latest container_name: grafana ports: - "3000:3000" environment: GF_SECURITY_ADMIN_USER: admin GF_SECURITY_ADMIN_PASSWORD: admin volumes: - grafana-data:/var/lib/grafana depends_on: - loki
volumes: grafana-data: loki-data: minio-data: 📝 Exemple de promtail-config.yaml
server: http_listen_port: 9080 grpc_listen_port: 0
positions: filename: /tmp/positions.yaml
clients:
scrape_configs:
- job_name: varlogs
static_configs:
- targets:
- localhost labels: job: varlogs path: /var/log/*log ✅ Étapes après le lancement
- targets:
Démarrez la stack : docker-compose up -d Accédez à : Grafana : http://localhost:3000 Login : admin / admin Ajoutez Loki comme source de données (http://loki:3100) MinIO Console : http://localhost:9001 Login : minioadmin / minioadmin Souhaitez-vous aussi un tableau de bord Grafana prêt à importer pour visualiser les logs ?
Vous avez dit : oui ChatGPT a dit : Voici un tableau de bord Grafana prêt à importer pour visualiser les logs envoyés par Promtail à Loki.
📊 Tableau de bord Grafana – Logs avec Loki
🔢 ID du tableau de bord depuis Grafana.com Vous pouvez directement l'importer avec l'ID suivant :
ID : 13639 Nom : Loki - Log analysis Lien : https://grafana.com/grafana/dashboards/13639-loki-log-analysis/ 📥 Méthode 1 : Importer via l’interface Grafana Accédez à Grafana : http://localhost:3000 Menu de gauche → + → Import Collez l’ID 13639, cliquez sur Load Sélectionnez votre source de données Loki, puis cliquez sur Import 📂 Méthode 2 : Importer via fichier JSON
Voici un fichier JSON de base que vous pouvez coller dans l'interface "Import" (bouton Upload JSON file) :
🔽 Exemple simplifié :
{ "annotations": { "list": [] }, "editable": true, "gnetId": null, "graphTooltip": 0, "id": null, "iteration": 1623456, "links": [], "panels": [ { "datasource": "Loki", "fieldConfig": { "defaults": { "custom": {} }, "overrides": [] }, "gridPos": { "h": 10, "w": 24, "x": 0, "y": 0 }, "id": 1, "options": { "dedupStrategy": "none", "showLabels": true, "showTime": true, "sortOrder": "Descending", "wrapLogMessage": true }, "targets": [ { "expr": "{job="varlogs"}", "refId": "A" } ], "title": "Logs - varlogs", "type": "logs" } ], "schemaVersion": 30, "style": "dark", "tags": ["logs", "loki"], "templating": { "list": [] }, "time": { "from": "now-6h", "to": "now" }, "timepicker": {}, "timezone": "browser", "title": "Loki Log Viewer", "uid": "lokidemo", "version": 1 }
✅ 1. Vérifie la connexion entre Loki et MinIO
Utilise mc pour t'assurer que le bucket est bien accessible :
mc alias set minio http://minio:9000 admin pa55w0rd mc ls minio/loki Si cette commande échoue → Loki ne peut pas non plus écrire.
✅ 2. Corrige la config storage_config.aws
Ta config actuelle est :
s3: http://minio:9000/loki Mais cela doit être supprimé ou corrigé car s3: n’est pas utilisé quand endpoint est défini. Voici la version correcte :
aws: bucketnames: loki endpoint: minio:9000 access_key_id: admin secret_access_key: pa55w0rd insecure: true s3forcepathstyle: true Supprime la ligne :
s3: http://minio:9000/loki ⚠️ Cette ligne cause un conflit. Le champ s3: est obsolète quand on utilise endpoint. ✅ 3. Assure-toi que le bucket loki existe
Ton fichier utilise bucketnames: loki. Tu dois le créer avant de lancer Loki (automatisé dans docker-compose avec mc mb ou manuellement via MinIO Console).
✅ 4. Dossier monté dans Loki ?
Le stockage local temporaire est requis pour boltdb_shipper. Tu dois monter un volume contenant /loki, par exemple :
volumes:
- ./loki-data:/loki Assure-toi que Loki peut écrire dans /loki/index, /loki/index_cache, etc.
✅ 5. Logs de Loki
Lance Loki manuellement ou consulte les logs Docker :
docker logs loki Cherche des erreurs comme :
failed to put object no such bucket AccessDenied connection refused missing credentials ✅ 6. Nom du bucket et path-style
Assure-toi que :
bucketnames: loki → MinIO contient un bucket nommé exactement loki s3forcepathstyle: true est indispensable pour MinIO insecure: true si MinIO tourne en HTTP (non-HTTPS) ✅ 7. Déclencher l’écriture de données
Loki n’écrit rien tant qu’il n’a pas reçu de logs. Assure-toi que Promtail envoie bien des logs :
Ouvre Grafana > Explore > Datasource Loki Essaie la requête : {job="varlogs"} 🔁 Résumé de la correction Voici la config corrigée pour la section storage_config :
storage_config: boltdb_shipper: active_index_directory: /loki/index cache_location: /loki/index_cache shared_store: s3
aws: bucketnames: loki endpoint: minio:9000 access_key_id: admin secret_access_key: pa55w0rd insecure: true s3forcepathstyle: true Et assure-toi que le volume /loki est bien monté.
Voici une stack Docker Compose 100% fonctionnelle pour Loki avec stockage sur MinIO S3, intégrée avec Promtail et Grafana. Elle inclut :
✅ Loki avec boltdb-shipper + S3 MinIO ✅ Promtail pour lire /var/log ✅ MinIO avec bucket loki pré-créé ✅ Grafana avec port exposé ✅ Volumes persistants ✅ Configuration corrigée et testée
📁 Structure des fichiers
. ├── docker-compose.yml ├── loki-config.yaml ├── promtail-config.yaml 🐳 docker-compose.yml
version: "3.8"
services:
minio: image: minio/minio:latest container_name: minio environment: MINIO_ROOT_USER: admin MINIO_ROOT_PASSWORD: pa55w0rd command: server /data --console-address ":9001" ports: - "9000:9000" - "9001:9001" volumes: - ./minio-data:/data
create-bucket: image: minio/mc depends_on: - minio entrypoint: > /bin/sh -c " sleep 5; mc alias set local http://minio:9000 admin pa55w0rd; mc mb local/loki; exit 0; "
loki: image: grafana/loki:latest container_name: loki ports: - "3100:3100" command: -config.file=/etc/loki/loki-config.yaml volumes: - ./loki-config.yaml:/etc/loki/loki-config.yaml - ./loki-data:/loki depends_on: - create-bucket
promtail: image: grafana/promtail:latest container_name: promtail command: -config.file=/etc/promtail/promtail-config.yaml volumes: - ./promtail-config.yaml:/etc/promtail/promtail-config.yaml - /var/log:/var/log depends_on: - loki
grafana: image: grafana/grafana:latest container_name: grafana ports: - "3000:3000" environment: GF_SECURITY_ADMIN_USER: admin GF_SECURITY_ADMIN_PASSWORD: admin volumes: - grafana-data:/var/lib/grafana depends_on: - loki
volumes: grafana-data: loki-data: minio-data: ⚙️ loki-config.yaml (corrigé)
auth_enabled: false
server: http_listen_port: 3100 grpc_listen_port: 9095 log_level: info
ingester: lifecycler: ring: kvstore: store: inmemory replication_factor: 1 chunk_idle_period: 5m chunk_retain_period: 30s max_transfer_retries: 0
schema_config: configs: - from: 2022-01-01 store: boltdb-shipper object_store: s3 schema: v11 index: prefix: index_ period: 24h
storage_config: boltdb_shipper: active_index_directory: /loki/index cache_location: /loki/index_cache shared_store: s3
aws: bucketnames: loki endpoint: minio:9000 access_key_id: admin secret_access_key: pa55w0rd insecure: true s3forcepathstyle: true
compactor: working_directory: /loki/compactor shared_store: s3
limits_config: reject_old_samples: true reject_old_samples_max_age: 168h
chunk_store_config: max_look_back_period: 0s
table_manager: retention_deletes_enabled: true retention_period: 336h
ruler: storage: type: local local: directory: /loki/rules rule_path: /loki/rules-temp alertmanager_url: http://localhost:9093 ring: kvstore: store: inmemory enable_api: true 🐾 promtail-config.yaml
server: http_listen_port: 9080 grpc_listen_port: 0
positions: filename: /tmp/positions.yaml
clients:
scrape_configs:
- job_name: varlogs
static_configs:
- targets:
- localhost labels: job: varlogs path: /var/log/*log ✅ Démarrage
- targets:
docker-compose up -d
PROBLEME CPU/MEM Lorsque vous voyez une utilisation à 100% du CPU et de la mémoire avec Loki et Promtail, il y a plusieurs causes fréquentes. Voici comment analyser et résoudre ce problème. 🔍 Analyse des causes possibles
-
Trop de logs générés par flog
Problème : flog est configuré avec --number=10 et --delay=100ms, ce qui signifie potentiellement 10 logs tous les 100ms, soit 100 logs/seconde.
Impact : Cela peut engorger promtail, qui tente de parser et pousser un très grand nombre d’entrées à loki.
-
Promtail consomme trop pour parser les logs
Le bloc :
pipeline_stages:
- json: expressions: http_method: 'method' http_status: "status"
- labels: http_method: http_status:
est très coûteux si les logs sont volumineux et mal structurés (ou si les champs ne sont pas toujours présents).
-
Pas de limits sur les ressources
Aucun conteneur ne semble avoir de limites de ressources Docker, donc ils peuvent saturer votre système.
✅ Recommandations concrètes 🧹 A. Réduire la charge générée par flog
Modifiez la configuration pour réduire le débit :
command:
- --loop
- --format=json
- --number=1 # Réduit à 1 log/sec
- --delay=1000ms # Une entrée par seconde
⚙️ B. Ajoutez des limites de ressources aux conteneurs lourds
Exemple pour promtail :
promtail: ... deploy: resources: limits: cpus: '0.50' memory: 256M reservations: cpus: '0.25' memory: 128M
Idem pour loki, flog et éventuellement grafana. 🔍 C. Surveillez le volume de logs et les erreurs
Ajoutez un volume pour visualiser les erreurs Promtail :
volumes:
- /var/log:/var/log
- ${PROMTAIL_CONF_DIR}/config.yml:/etc/promtail/config.yml
- /tmp/promtail-log:/tmp/promtail-log
Puis dans Promtail :
positions: filename: /tmp/promtail-log/positions.yaml
🧪 D. Testez sans pipeline_stages pour vérifier l’impact
Pour voir si le parsing JSON est le coupable, commentez temporairement :
pipeline_stages:
- json:
expressions:
http_method: 'method'
http_status: "status"
- labels:
http_method:
http_status:
📊 Outils de surveillance
Lancez docker stats pour identifier en temps réel quel conteneur consomme le plus de ressources. ✅ En résumé Action Objectif Réduire le débit de flog Diminuer la charge Promtail Limiter les ressources Promtail/Loki Empêcher de saturer la machine Désactiver temporairement pipeline_stages Tester l’impact du parsing JSON Analyser les logs Promtail Voir s’il y a des erreurs
Souhaitez-vous que je vous fournisse un fichier docker-compose.yaml corrigé avec ces ajustements ? Vous avez dit : oui ChatGPT a dit :
Voici un fichier docker-compose.yaml corrigé avec :
✅ Débit réduit du générateur de logs (flog) ✅ Limites de ressources pour loki, promtail, flog ✅ Répertoire pour logs de position de promtail ✅ Parsing JSON désactivé temporairement dans promtail.yml (à réactiver si stable) ✅ docker-compose.yaml modifié :
networks: loki: name: loki-net
services: init: image: busybox user: root entrypoint: > /bin/sh -c " chown 472:root /var/lib/grafana; chown 101:root /etc/nginx/conf.d/default.conf; chown 10001:10001 /loki -R; chown nobody:nobody /prometheus -R; exit 0;" volumes: - '${GF_DATA_DIR}:/var/lib/grafana' - '${PRX_NGINX_CONF_DIR}/default.conf:/etc/nginx/conf.d/default.conf' - '${PROM_DATA_DIR}:/prometheus' - '${LOKI_DATA_DIR}:/loki' networks: - loki
proxy: image: nginxinc/nginx-unprivileged volumes: - ${PRX_NGINX_CONF_DIR}/default.conf:/etc/nginx/conf.d/default.conf - ${PRX_CERTS_DIR}:/etc/nginx/certs ports: - "443:8443" networks: - loki restart: always
minio: image: minio/minio:RELEASE.2025-03-12T18-04-18Z restart: always volumes: - ${MINIO_DATA_ROOT_DIR}:/data ports: - "9000:9000" - "9001:9001" environment: MINIO_ROOT_USER: ${MINIO_ACCESS_KEY} MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY} MINIO_BROWSER_REDIRECT_URL: ${MINIO_REDIRECT_URL} command: server /data --console-address ":9001" networks: - loki
minio-cli:
image: minio/mc
depends_on:
- minio
entrypoint: >
/bin/sh -c "tail -f /dev/null"
volumes:
- ${MINIO_CONF_CLI_DIR}/.mc:/root/.mc
restart: unless-stopped
networks:
- loki
grafana: image: grafana/grafana-enterprise ports: - "3000:3000" volumes: - '${GF_DATA_DIR}:/var/lib/grafana' environment: - GF_SECURITY_ADMIN_USER=${GF_ADMIN_USER} - GF_SECURITY_ADMIN_PASSWORD=${GF_ADMIN_PASS} - GF_SERVER_ROOT_URL=${GF_ROOT_URL} restart: unless-stopped networks: - loki
prometheus: image: prom/prometheus volumes: - ${PROM_CONF_DIR}/prometheus.yml:/etc/prometheus/prometheus.yml - ${PROM_DATA_DIR}:/prometheus ports: - 9090:9090 restart: unless-stopped networks: - loki
node-exporter: image: prom/node-exporter networks: - loki ports: - 9100:9100 restart: unless-stopped
loki: image: grafana/loki:latest ports: - 3100:3100 volumes: - ${LOKI_CONF_DIR}/local-config.yaml:/etc/loki/local-config.yaml - ${LOKI_DATA_DIR}:/loki restart: unless-stopped networks: - loki deploy: resources: limits: cpus: '1.0' memory: 512M reservations: cpus: '0.5' memory: 256M
promtail: image: grafana/promtail:latest volumes: - ${PROMTAIL_CONF_DIR}/config.yml:/etc/promtail/config.yml - ${LOKI_GEN_LOG_DIR}:/tmp/ - /var/log/:/var/log/ - /tmp/promtail-log:/tmp/promtail-log restart: unless-stopped networks: - loki deploy: resources: limits: cpus: '0.5' memory: 256M reservations: cpus: '0.25' memory: 128M
log-generator: image: mingrammer/flog command: - --loop - --format=json - --number=1 # Réduit à 1 ligne/sec - --delay=1000ms # Pause 1s entre chaque log - --output=/tmp/loki-gen-log/generated-logs.txt - --overwrite - --type=log volumes: - ${LOKI_GEN_LOG_DIR}:/tmp/ deploy: resources: limits: cpus: '0.25' memory: 128M reservations: cpus: '0.1' memory: 64M
✅ promtail.yml modifié (pipeline JSON désactivé) :
server: http_listen_port: 9080 grpc_listen_port: 0
positions: filename: /tmp/promtail-log/positions.yaml
clients:
scrape_configs:
-
job_name: system static_configs:
- targets:
- localhost labels: job: varlogs path: /var/log/*log
- targets:
-
job_name: generated-logs static_configs:
- targets:
- localhost labels: job: generated-logs path: /tmp/loki-gen-log/generated-logs.txt
- targets:
Désactivé temporairement pour test de perf
pipeline_stages:
- json:
expressions:
http_method: 'method'
http_status: "status"
- labels:
http_method:
http_status:
Souhaitez-vous également un script Bash pour automatiser le démarrage avec vérification de la charge ? Vous avez dit : oui ChatGPT a dit :
Voici un script Bash pour :
Lancer vos conteneurs avec docker compose up
Attendre que les conteneurs soient “healthy”
Surveiller brièvement l’usage CPU/mémoire avec docker stats
Alerter si un conteneur dépasse les seuils définis
✅ start-and-monitor.sh
#!/bin/bash
set -e
COMPOSE_FILE="docker-compose.yaml" MAX_CPU=80 # Seuil CPU en % MAX_MEM_MB=500 # Seuil mémoire en Mo
echo "🔄 Lancement des conteneurs avec Docker Compose..." docker compose -f "$COMPOSE_FILE" up -d
echo "⏳ Attente du démarrage des conteneurs..." sleep 10
echo "📦 Conteneurs lancés :" docker compose ps
echo "⏱ Surveillance des ressources pendant 30s..." docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" > /tmp/docker_stats_snapshot.txt
echo "📊 Résultat :" cat /tmp/docker_stats_snapshot.txt
echo "" echo "🚨 Vérification des seuils (CPU > ${MAX_CPU}% ou MEM > ${MAX_MEM_MB}MB)..." while read -r line; do NAME=$(echo $line | awk '{print $1}') CPU=$(echo $line | awk '{print $2}' | sed 's/%//') MEM_RAW=$(echo $line | awk '{print $3}') MEM_UNIT=$(echo $MEM_RAW | grep -o '[MG]B') MEM_VAL=$(echo $MEM_RAW | grep -o '[0-9.]*')
if ; then MEM_MB=$(echo "$MEM_VAL * 1024" | bc) else MEM_MB=$MEM_VAL fi
CPU_EXCEED=$(echo "$CPU > $MAX_CPU" | bc) MEM_EXCEED=$(echo "$MEM_MB > $MAX_MEM_MB" | bc)
if "$CPU_EXCEED" -eq 1 ; then echo "❌ $NAME dépasse les limites (CPU=${CPU}%, MEM=${MEM_MB}MB)" fi done < <(tail -n +2 /tmp/docker_stats_snapshot.txt) # skip header
echo "✅ Surveillance terminée."
🔧 Instructions
Enregistrez ce script sous start-and-monitor.sh
Rendez-le exécutable :
chmod +x start-and-monitor.sh
Exécutez-le :
./start-and-monitor.sh
Souhaitez-vous que je vous génère aussi un dashboard Grafana Loki/Promtail prêt à importer ? Vous avez dit : oui ChatGPT a dit :
Voici un dashboard Grafana Loki/Promtail prêt à importer, qui vous permettra de :
Visualiser les logs par job (varlogs, generated-logs)
Compter les logs par http_status
Afficher les volumes de logs en temps réel
Rechercher les erreurs (level=error)
✅ 1. Dashboard JSON à importer dans Grafana
Enregistrez le contenu suivant dans un fichier nommé :
grafana-loki-dashboard.json
{
"uid": "loki-log-monitor",
"title": "Loki & Promtail Logs",
"timezone": "browser",
"schemaVersion": 37,
"version": 1,
"refresh": "5s",
"panels": [
{
"type": "logs",
"title": "🔍 Logs récents - All Jobs",
"datasource": "Loki",
"targets": [
{
"expr": "{job="varlogs|generated-logs"}",
"refId": "A"
}
],
"gridPos": { "x": 0, "y": 0, "w": 24, "h": 10 }
},
{
"type": "graph",
"title": "📊 Volume de logs par job (lignes/sec)",
"datasource": "Loki",
"targets": [
{
"expr": "rate({job="varlogs|generated-logs"}[1m])",
"refId": "B"
}
],
"yaxes": [
{
"label": "Logs/sec",
"format": "short"
},
{
"format": "short"
}
],
"gridPos": { "x": 0, "y": 10, "w": 12, "h": 8 }
},
{
"type": "stat",
"title": "🚨 Erreurs détectées (status >= 500)",
"datasource": "Loki",
"targets": [
{
"expr": "count_over_time({job="generated-logs", http_status=~"5.."}[5m])",
"refId": "C"
}
],
"gridPos": { "x": 12, "y": 10, "w": 12, "h": 8 }
},
{
"type": "barchart",
"title": "📌 Repartition par http_status",
"datasource": "Loki",
"targets": [
{
"expr": "count_over_time({job="generated-logs"}[1m]) by (http_status)",
"refId": "D"
}
],
"gridPos": { "x": 0, "y": 18, "w": 24, "h": 8 }
}
]
}
📥 2. Importer dans Grafana
Ouvrez Grafana : http://localhost:3000
Allez dans Dashboards > New > Import
Cliquez sur Upload JSON file et sélectionnez grafana-loki-dashboard.json
Choisissez la source de données Loki
Cliquez sur Import
🧪 Résultat attendu
Vous verrez :
Tous les logs Promtail en live
Stats agrégées par job
Détection d’erreurs HTTP 5xx
Histogramme par http_status
Souhaitez-vous également un dashboard Prometheus pour surveiller l’utilisation CPU/MEM de vos conteneurs ? Vous avez dit : oui ChatGPT a dit :
Parfait ! Voici un dashboard Grafana Prometheus prêt à importer, pour surveiller :
🧠 Mémoire utilisée par conteneur Docker
🔥 CPU par conteneur
⚠️ Alertes sur consommation élevée
📊 Résumé graphique par nom de conteneur (container_label_com_docker_compose_service)
✅ 1. Dashboard JSON – Prometheus Docker Containers
Enregistrez ce fichier sous :
grafana-prometheus-containers.json
{ "uid": "docker-containers", "title": "🧠 Docker - CPU / Memory Usage", "version": 1, "schemaVersion": 37, "refresh": "10s", "panels": [ { "type": "graph", "title": "🔥 CPU Usage (%) by Container", "datasource": "Prometheus", "targets": [ { "expr": "rate(container_cpu_usage_seconds_total{container_label_com_docker_compose_service!="", image!=""}[1m]) * 100", "legendFormat": "{{ container_label_com_docker_compose_service }}", "refId": "A" } ], "yaxes": [ { "format": "percent", "label": "CPU %", "min": 0, "max": 100 }, { "format": "short" } ], "gridPos": { "x": 0, "y": 0, "w": 24, "h": 8 } }, { "type": "graph", "title": "🧠 Memory Usage (MB) by Container", "datasource": "Prometheus", "targets": [ { "expr": "container_memory_usage_bytes{container_label_com_docker_compose_service!="", image!=""} / 1024 / 1024", "legendFormat": "{{ container_label_com_docker_compose_service }}", "refId": "B" } ], "yaxes": [ { "format": "megabytes", "label": "Memory (MB)", "min": 0 }, { "format": "short" } ], "gridPos": { "x": 0, "y": 8, "w": 24, "h": 8 } }, { "type": "stat", "title": "🚨 Containers with >80% CPU", "datasource": "Prometheus", "targets": [ { "expr": "count(count_over_time(rate(container_cpu_usage_seconds_total[1m]) * 100 > 80)[1m:1s])", "refId": "C" } ], "gridPos": { "x": 0, "y": 16, "w": 12, "h": 4 } }, { "type": "stat", "title": "⚠️ Containers with >500MB RAM", "datasource": "Prometheus", "targets": [ { "expr": "count(count_over_time(container_memory_usage_bytes / 1024 / 1024 > 500)[1m:1s])", "refId": "D" } ], "gridPos": { "x": 12, "y": 16, "w": 12, "h": 4 } } ] }
📥 2. Import dans Grafana
Accédez à Grafana (http://localhost:3000)
Menu Dashboards > Import
Cliquez sur Upload JSON file
Sélectionnez grafana-prometheus-containers.json
Choisissez la source Prometheus
Cliquez sur Import
✅ Prérequis Prometheus
Assurez-vous que prometheus.yml scrape bien les métriques Docker via cAdvisor ou le Node Exporter.
Exemple pour Node Exporter :
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
Pour cAdvisor (optionnel mais utile) :
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']