RousselTMLEARNING

Observabilité

Grafana : maîtriser les requêtes (PromQL, LogQL, SQL et expressions)

Construire des requêtes efficaces dans Grafana : éditeur de requêtes, Query Inspector, PromQL, LogQL, SQL, Mixed datasource, expressions, options de requête et optimisation.

1. L'éditeur de requêtes #

Explore, panneaux et Query Inspector.

Où écrire une requête ? #

Cycle de vie d'une requête Grafana
Les expressions et transformations s'exécutent après les requêtes.
  • Explore : écrire et tester des requêtes sans créer de dashboard, comparer deux sources côte à côte.
  • Panneau : chaque panneau contient une ou plusieurs requêtes (A, B, C...) sur une ou plusieurs sources (mode Mixed).
  • Query Inspector : onglets Stats, JSON, Data, Query pour comprendre ce qui est réellement envoyé.
# Variables de requête utiles (Prometheus)
$__interval        # intervalle calculé selon la largeur du graphique
$__rate_interval   # fenêtre sûre pour rate() : max(4 x scrape, $__interval)
$__range           # durée de la plage de temps sélectionnée
$instance          # variable du dashboard
${instance:regex}  # format de variable pour les expressions régulières

2. Interroger Prometheus (PromQL) #

Les patterns de base.

Quelques requêtes typiques #

# Taux de requêtes par statut
sum by (status) (rate(http_requests_total{job="api"}[$__rate_interval]))

# Top 5 des instances par CPU
topk(5, 100 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[$__rate_interval])) * 100)

# Disponibilité sur la plage affichée
avg_over_time(up{job="api"}[$__range]) * 100
Bonne Pratique : Activez l'option Format : Time series / Table / Heatmap et l'option Type : Range / Instant adaptée : un Stat ou une Table doit utiliser Instant pour limiter la charge.

3. Interroger Loki (LogQL) et les bases SQL #

Logs et données relationnelles.

LogQL #

# Logs d'une application contenant "error"
{app="checkout", env="prod"} |= "error" != "healthcheck"

# Parser du JSON et filtrer
{app="checkout"} | json | level="error" | line_format "{{.method}} {{.path}} {{.status}}"

# Transformer des logs en métrique : erreurs par minute
sum by (app) (rate({env="prod"} |= "error" [1m]))

# Top 10 des chemins les plus lents (quantile)
quantile_over_time(0.95, {app="api"} | json | unwrap duration_ms [5m]) by (path)

SQL (PostgreSQL, MySQL) #

-- Série temporelle : commandes par heure
SELECT $__timeGroupAlias(created_at, '1h'),
       count(*) AS commandes
FROM orders
WHERE $__timeFilter(created_at)
GROUP BY 1
ORDER BY 1;

-- Table : top clients
SELECT customer, sum(total) AS chiffre_affaires
FROM orders
WHERE $__timeFilter(created_at)
GROUP BY customer ORDER BY 2 DESC LIMIT 10;
Erreur Courante : Utilisez un compte de base de données en lecture seule pour la source de données Grafana et limitez les requêtes coûteuses (LIMIT, index sur la colonne de temps).

4. Combiner et optimiser #

Mixed, expressions et performances.

Mixed datasource et expressions #

La source -- Mixed -- permet d'interroger plusieurs sources dans un même panneau. Les expressions (Math, Reduce, Resample) calculent à partir des résultats des requêtes précédentes, par exemple le ratio entre deux sources :

A : sum(rate(http_requests_total{status=~"5.."}[$__rate_interval]))    (Prometheus)
B : sum(rate(http_requests_total[$__rate_interval]))                   (Prometheus)
C (Math) : $A / $B * 100                                                (expression)

Optimiser #

  • Limiter la plage de temps et l'intervalle de rafraîchissement des dashboards.
  • Utiliser Max data points et Min interval pour réduire le volume de points retournés.
  • Activer Query caching (Grafana Enterprise/Cloud) ou les recording rules Prometheus pour les requêtes lourdes.
  • Remplacer une dizaine de panneaux identiques par un panneau Repeat basé sur une variable.
# Recording rule Prometheus pour précalculer une requête lourde
groups:
  - name: precalcul
    rules:
      - record: job:http_requests:rate5m
        expr: sum by (job) (rate(http_requests_total[5m]))

Pour aller plus loin