grafana-loki-minio/FROM-AI.md
2025-06-13 17:07:45 +02:00

27 KiB
Raw Blame History

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 lingestion 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

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 linterface Grafana Accédez à Grafana : http://localhost:3000 Menu de gauche → + → Import Collez lID 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: nest 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 quil na 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

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

  1. 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 dentrées à loki.

  2. 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).

  3. 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 limpact

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 limpact du parsing JSON Analyser les logs Promtail Voir sil 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
  • job_name: generated-logs static_configs:

    • targets:
      • localhost labels: job: generated-logs path: /tmp/loki-gen-log/generated-logs.txt

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 lusage 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 derreurs HTTP 5xx

Histogramme par http_status

Souhaitez-vous également un dashboard Prometheus pour surveiller lutilisation 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']