MDstable
NoteSnippetChecklistPlaybook

Grafana — Dashboards et visualisation

Grafana en Docker : datasources, dashboards, alerting, provisioning, panels PromQL et Loki

snippetintermediate 2026-05-26 4 min read
grafanaprometheuslokidashboardsalertingprovisioningdockermetrics

Déploiement Docker

yaml
# docker-compose.yml
services:
grafana:
image: grafana/grafana:10.4.2
ports: ["3000:3000"]
environment:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: "${GRAFANA_PASSWORD}"
GF_USERS_ALLOW_SIGN_UP: "false"
GF_SERVER_ROOT_URL: "http://localhost:3000"
GF_SMTP_ENABLED: "true"
GF_SMTP_HOST: "smtp.example.com:587"
GF_SMTP_FROM_ADDRESS: "grafana@example.com"
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
- ./grafana/dashboards:/var/lib/grafana/dashboards
loki:
image: grafana/loki:3.0.0
ports: ["3100:3100"]
volumes:
- ./grafana/loki-config.yml:/etc/loki/local-config.yaml
- loki_data:/loki
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:3.0.0
volumes:
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./grafana/promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
volumes:
grafana_data:
loki_data:
bash
docker compose up -d grafana loki promtail
# Interface : http://localhost:3000 (admin / voir .env)

Provisioning — Datasources

yaml
# grafana/provisioning/datasources/datasources.yml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
jsonData:
timeInterval: "15s"
- name: Loki
type: loki
access: proxy
url: http://loki:3100
jsonData:
maxLines: 1000
- name: Elasticsearch
type: elasticsearch
access: proxy
url: http://elasticsearch:9200
basicAuth: true
basicAuthUser: elastic
secureJsonData:
basicAuthPassword: "${ELASTIC_PASSWORD}"
jsonData:
index: "logstash-*"
timeField: "@timestamp"
esVersion: "8.0.0"

Provisioning — Dashboards

yaml
# grafana/provisioning/dashboards/dashboards.yml
apiVersion: 1
providers:
- name: default
folder: Infra
type: file
options:
path: /var/lib/grafana/dashboards
foldersFromFilesStructure: true

Loki — Configuration

yaml
# grafana/loki-config.yml
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
replication_factor: 1
schema_config:
configs:
- from: 2024-01-01
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/index_cache
filesystem:
directory: /loki/chunks
limits_config:
retention_period: 30d
ingestion_rate_mb: 16
max_query_series: 5000

Promtail — Configuration

yaml
# grafana/promtail-config.yml
server:
http_listen_port: 9080
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: syslog
__path__: /var/log/syslog
- job_name: auth
static_configs:
- targets: [localhost]
labels:
job: auth
__path__: /var/log/auth.log
- job_name: docker
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: [__meta_docker_container_name]
target_label: container
- source_labels: [__meta_docker_container_log_stream]
target_label: stream

Panels PromQL courants

promql
# Gauge CPU (%)
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Time series — trafic réseau
rate(node_network_receive_bytes_total{device!="lo"}[5m]) * 8 / 1024 / 1024
# Stat — uptime serveur
(node_time_seconds - node_boot_time_seconds) / 3600 / 24
# Bar gauge — espace disque par volume
(node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes * 100
# Table — containers actifs avec RAM
container_memory_usage_bytes{name!=""} / 1024 / 1024

LogQL — Requêtes Loki

logql
# Tous les logs d'erreur SSH
{job="auth"} |= "Failed password"
# Logs par container
{container="nginx"} |= "error"
# Parser les logs Nginx (pattern)
{job="nginx"} | pattern `<ip> - - [<date>] "<method> <uri> <proto>" <status> <size>`
| status >= 500
# Compter les erreurs 5xx par minute
sum(rate({job="nginx"} | pattern `<_> <status> <_>` | status >= 500 [1m]))
# Filtrer par niveau de log
{container="app"} | json | level="error"

Alerting Grafana (Unified Alerting)

bash
# Via API — créer un contact point Slack
curl -X POST http//adminpasswordlocalhost3000/api/v1/provisioning/contact-points
-H "Content-Type: application/json"
-d
"name" "slack-ops"
"type" "slack"
"settings"
"url" "<SLACK_WEBHOOK_URL>"
"channel" "#alerts"
# Créer une règle d alerte via API
curl -X POST http//adminpasswordlocalhost3000/api/v1/provisioning/alert-rules
-H "Content-Type: application/json"
-d
"title" "CPU High"
"condition" "C"
"data"
"refId" "A"
"datasourceUid" "__expr__"
"model"
"expr" "100 - (avg(rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100) > 85"
"for" "5m"
"labels" "severity" "warning"
"annotations" "summary" "CPU élevé"
"folderUID" "infra"
"ruleGroup" "infra-alerts"

Commandes utiles

bash
# Vérifier la santé de Grafana
curl -s http//localhost3000/api/health | jq
# Lister les datasources
curl -s http//adminpasswordlocalhost3000/api/datasources | jq '.[].name'
# Exporter un dashboard (récupérer l'UID depuis l'URL)
curl -s http//adminpasswordlocalhost3000/api/dashboards/uid/<UID> | jq '.dashboard' > dashboardjson
# Importer un dashboard
curl -X POST http//adminpasswordlocalhost3000/api/dashboards/import
-H "Content-Type: application/json"
-d '{"dashboard": <JSON>, "overwrite": true, "folderId": 0}'
# Vérifier Loki
curl -s http//localhost3100/ready
curl -s "http://localhost:3100/loki/api/v1/query?query={job=\"auth\"}&limit=5" | jq
# Vérifier Promtail
curl -s http//localhost9080/metrics | grep promtail_sent_entries

Dashboards recommandés (import par ID)

| Dashboard | ID Grafana.com | Usage | |---|---|---| | Node Exporter Full | 1860 | Métriques système Linux | | cAdvisor | 14282 | Métriques containers Docker | | Docker | 893 | Vue globale Docker | | Loki Dashboard | 13639 | Logs agrégés | | Blackbox Exporter | 7587 | Sonde HTTP/TCP | | Alertmanager | 9578 | État des alertes |

bash
# Importer depuis Grafana.com via API
curl -X POST http//adminpasswordlocalhost3000/api/dashboards/import
-H "Content-Type: application/json"
-d '{"inputs":[{"name":"DS_PROMETHEUS","type":"datasource","pluginId":"prometheus","value":"Prometheus"}],"folderId":0,"overwrite":true,"path":"https://grafana.com/api/dashboards/1860/revisions/latest/download"}'
💡 Tip —

Utiliser le provisioning (fichiers YAML dans provisioning/) pour versionner datasources et dashboards dans Git. Évite la dérive de configuration et permet un redéploiement reproductible.

⚠ Attention —

Changer le mot de passe admin par défaut et désactiver GF_USERS_ALLOW_SIGN_UP. En production, activer HTTPS via reverse proxy et configurer GF_SERVER_ROOT_URL avec le FQDN public.

OPS·BRAIN v1.05 notes · Monitoringlocal