Aller au contenu principal

Grafana


1 - Présentation

Grafana est la plateforme de visualisation et d'observabilité la plus populaire.


2 - Installation

2.1 Docker

# docker-compose.yml
version: '3.8'
services:
grafana:
image: grafana/grafana:10.2.0
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
- ./provisioning:/etc/grafana/provisioning

volumes:
grafana_data:

2.2 Kubernetes

helm repo add grafana https://grafana.github.io/helm-charts
helm install grafana grafana/grafana \
--namespace monitoring \
--set adminPassword=admin \
--set persistence.enabled=true

3 - Data Sources

3.1 Provisioning

# provisioning/datasources/datasources.yml
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false

- name: Loki
type: loki
access: proxy
url: http://loki:3100

- name: Tempo
type: tempo
access: proxy
url: http://tempo:3200
jsonData:
tracesToLogs:
datasourceUid: loki
tags: ['service.name']

3.2 Configuration par API

# Créer une data source via API
curl -X POST http://admin:admin@localhost:3000/api/datasources \
-H "Content-Type: application/json" \
-d '{
"name": "Prometheus",
"type": "prometheus",
"url": "http://prometheus:9090",
"access": "proxy",
"isDefault": true
}'

4 - Dashboards

4.1 Structure JSON

{
"dashboard": {
"title": "My Dashboard",
"tags": ["monitoring", "production"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "Request Rate",
"type": "timeseries",
"gridPos": { "x": 0, "y": 0, "w": 12, "h": 8 },
"targets": [
{
"expr": "rate(http_requests_total[5m])",
"legendFormat": "{{method}} {{status}}"
}
]
}
],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
}
}
}

4.2 Provisioning Dashboards

# provisioning/dashboards/default.yml
apiVersion: 1

providers:
- name: 'default'
folder: 'Provisioned'
type: file
disableDeletion: true
updateIntervalSeconds: 30
options:
path: /etc/grafana/provisioning/dashboards

5 - Panels

5.1 Types de panels

PanelUsage
Time seriesGraphiques temporels
StatValeur unique
GaugeJauge visuelle
Bar gaugeBarres
TableDonnées tabulaires
HeatmapDistribution
LogsAffichage des logs

5.2 Time series

{
"type": "timeseries",
"fieldConfig": {
"defaults": {
"color": { "mode": "palette-classic" },
"custom": {
"drawStyle": "line",
"lineInterpolation": "smooth",
"fillOpacity": 20
},
"unit": "reqps"
}
},
"options": {
"legend": {
"displayMode": "table",
"placement": "bottom",
"calcs": ["mean", "max", "last"]
}
}
}

5.3 Stat Panel

{
"type": "stat",
"fieldConfig": {
"defaults": {
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 50 },
{ "color": "red", "value": 80 }
]
},
"unit": "percent"
}
},
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "horizontal"
}
}

6 - Variables (Templates)

6.1 Types de variables

variables:
# Query variable
- name: namespace
type: query
datasource: Prometheus
query: label_values(kube_pod_info, namespace)
refresh: on_time_range_change

# Custom variable
- name: environment
type: custom
options:
- { text: "Production", value: "prod" }
- { text: "Staging", value: "staging" }

# Interval variable
- name: interval
type: interval
options: ["1m", "5m", "15m", "1h"]
auto: true
auto_count: 30

6.2 Utilisation dans les queries

# Utiliser les variables
rate(http_requests_total{namespace="$namespace"}[$__interval])

# Multi-value
rate(http_requests_total{namespace=~"$namespace"}[5m])

6.3 Chained Variables

variables:
- name: cluster
query: label_values(kube_pod_info, cluster)

- name: namespace
query: label_values(kube_pod_info{cluster="$cluster"}, namespace)

- name: pod
query: label_values(kube_pod_info{cluster="$cluster", namespace="$namespace"}, pod)

7 - Alerting

7.1 Alert Rules

# Alert rule via provisioning
apiVersion: 1
groups:
- name: http-alerts
folder: HTTP
interval: 1m
rules:
- uid: high-error-rate
title: High Error Rate
condition: B
data:
- refId: A
relativeTimeRange:
from: 300
to: 0
datasourceUid: prometheus
model:
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m])) * 100
- refId: B
relativeTimeRange:
from: 0
to: 0
datasourceUid: '-100'
model:
conditions:
- evaluator:
params: [5]
type: gt
operator:
type: and
query:
params: [A]
reducer:
type: avg
for: 5m
labels:
severity: critical
annotations:
summary: "Error rate above 5%"

7.2 Contact Points

# Contact point configuration
contactPoints:
- name: slack-notifications
receivers:
- uid: slack
type: slack
settings:
url: https://hooks.slack.com/services/xxx
recipient: "#alerts"

- name: pagerduty-critical
receivers:
- uid: pagerduty
type: pagerduty
settings:
integrationKey: xxx
severity: critical

7.3 Notification Policies

policies:
- receiver: slack-notifications
group_by: ['alertname', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- receiver: pagerduty-critical
matchers:
- severity = critical
continue: true

8 - Dashboard Best Practices

8.1 Layout recommandé

┌─────────────────────────────────────────────────┐
│ Variables │
├─────────────────────────────────────────────────┤
│ Request Rate │ Error Rate │ Latency P99 │ Uptime│ <- Stat panels
├─────────────────────────────────────────────────┤
│ │
│ Request Rate Graph │ <- Time series
│ │
├─────────────────────────────────────────────────┤
│ │
│ Latency Distribution │ <- Heatmap
│ │
├─────────────────────────────────────────────────┤
│ Top Endpoints Table │ <- Table
└─────────────────────────────────────────────────┘

8.2 Conventions

AspectRecommandation
CouleursVert=OK, Jaune=Warning, Rouge=Critical
NomsDescriptifs, incluant l'unité
RequêtesUtiliser des Recording Rules
VariablesNamespace, Environment, Service

Résumé

Dans ce chapitre, nous avons appris :

  • L'installation de Grafana
  • La configuration des Data Sources
  • La création de Dashboards
  • Les différents types de Panels
  • Les Variables et templates
  • L'Alerting intégré
  • Les bonnes pratiques

Prochaine étape

Dans le prochain chapitre, nous verrons ELK Stack.

→ Chapitre suivant : ELK Stack


← Retour à la table des matières