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: - url: http://loki:3100/loki/api/v1/push 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 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: - url: http://loki:3100/loki/api/v1/push 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 d’entré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 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: - url: http://loki:3100/loki/api/v1/push 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 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 [[ $MEM_UNIT == "GB" ]]; 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 || "$MEM_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']