Retour au cours

infra / monitoring-observabilite

PromQL avancé

Leçon 51 exercice

Explication

Ce que vous allez apprendre

  • Joindre deux métriques différentes avec group_left/group_right pour enrichir un résultat
  • Anticiper une saturation future avec predict_linear()
  • Identifier rapidement les séries extrêmes avec topk() et bottomk()
  • Détecter la disparition totale d'une métrique avec absent()
  • Pré-calculer des requêtes coûteuses avec des recording rules

Dans quel contexte ?

Une équipe SRE surveille une trentaine de services, mais les alertes actuelles ne remontent que des taux d'erreur bruts sans savoir à quelle équipe ni quel environnement ils appartiennent. Le PromQL de base (leçon précédente) filtre et agrège une seule métrique à la fois ; il faut maintenant apprendre à combiner plusieurs métriques et à anticiper des problèmes avant qu'ils n'arrivent.

D'abord, un cas très courant : comparer deux métriques entre elles

Les opérateurs binaires (/, >, -) fonctionnent aussi entre deux résultats PromQL complets, à condition que leurs labels correspondent. C'est ainsi qu'on calcule un taux d'erreur par service : diviser le débit d'erreurs par le débit total, puis filtrer avec > 0.05 pour ne garder que les services vraiment problématiques.

Ce filtrage par comparaison transforme une métrique numérique en une sorte de "requête booléenne" : le résultat ne contient plus que les séries qui satisfont la condition, les autres disparaissent silencieusement du résultat.

Une fois ça acquis, il reste un problème : comment enrichir une métrique technique avec du contexte métier ?

Une métrique technique comme http_requests_total ne connaît généralement pas l'équipe propriétaire ou l'environnement business du service. Ces informations vivent parfois dans une métrique séparée, purement informative (valeur toujours égale à 1), qui ne sert qu'à porter des labels.

C'est le rôle de group_left/group_right : joindre deux métriques de cardinalités différentes, un peu comme une jointure SQL "many-to-one". group_left signifie que le côté gauche de l'opération peut avoir plusieurs séries pour une seule série du côté droit.

Fonction avancéeRôleCas d'usage typique
group_left/group_rightJointure entre métriques de cardinalités différentesEnrichir avec des labels métier (équipe, environnement)
predict_linear()Extrapolation linéaire dans le futurAnticiper une saturation disque/mémoire
topk()/bottomk()N séries les plus/moins élevées"Qui consomme le plus", "quelle instance est la moins fiable"
absent()Détecte l'absence totale d'une sérieAlerter si un exporter a disparu du scraping

Prérequis

Cette leçon suppose une bonne maîtrise du PromQL de base : rate(), sum(...) by (...) et les filtres par label doivent déjà être des réflexes avant d'aborder les jointures.

Maintenant, une capacité que peu de systèmes de monitoring offrent nativement : prédire l'avenir

predict_linear() prend les valeurs des dernières heures d'une Gauge et extrapole linéairement leur évolution dans le futur. Appliqué à l'espace disque libre, il permet d'alerter "ce disque sera plein dans 4 heures" plutôt que d'attendre qu'il le soit réellement.

Astuce

Combine predict_linear() avec un for: généreux (10 à 15 minutes) dans tes règles d'alerte : une extrapolation basée sur un pic ponctuel et transitoire donnerait sinon de fausses alertes de saturation imminente.

Il reste un dernier cas particulier, contre-intuitif au premier abord : l'absence de données

Toutes les fonctions vues jusqu'ici travaillent sur des séries qui EXISTENT. Mais que se passe-t-il si un exporter tombe complètement en panne et arrête d'envoyer la moindre métrique ? Aucune des requêtes précédentes ne peut détecter ce silence, puisqu'il n'y a tout simplement plus rien à interroger.

Piège fréquent

Une alerte du type up{job="mon_api"} == 0 ne se déclenche QUE si la série up existe encore mais vaut 0. Si le job disparaît totalement de la configuration de scraping (erreur de déploiement, service supprimé par erreur), cette alerte reste silencieuse. absent(up{job="mon_api"}) couvre ce cas en détectant l'absence complète de la série elle-même.

Pour finir, un mot sur la performance : les recording rules

Une requête PromQL complexe, réutilisée dans dix dashboards différents et recalculée à chaque rafraîchissement, finit par coûter cher en ressources. Les recording rules pré-calculent ce résultat en arrière-plan, à intervalle régulier, et le stockent sous un nouveau nom de métrique bien plus rapide à interroger ensuite.

Maintenant que la manipulation de métriques n'a plus de secret, la suite logique est de leur donner une forme visuelle exploitable : direction Grafana pour construire de vrais dashboards.

Commandes & code

PromQL avancé

promql
# Opérateurs binaires entre séries : jointure automatique sur les labels communs
(
  sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
  /
  sum(rate(http_requests_total[5m])) by (service)
) > 0.05
# -> ne garde que les services dont le taux d'erreur dépasse 5% (filtre booléen sur le résultat)
promql
# group_left / group_right : jointure many-to-one entre métriques aux cardinalités différentes
# Exemple : enrichir une métrique technique avec un label métier venant d'une autre métrique
sum(rate(http_requests_total[5m])) by (instance)
* on(instance) group_left(team, env)
service_info{}
# service_info est une métrique "statique" (valeur=1) qui sert juste à porter des labels supplémentaires
promql
# predict_linear() : extrapolation linéaire — utile pour anticiper une saturation
predict_linear(node_filesystem_free_bytes[6h], 4 * 3600) < 0
# -> prédit si l'espace disque libre atteindra 0 dans les 4 prochaines heures, sur la base des 6 dernières heures

# deriv() : dérivée (pente) d'une gauge dans le temps
deriv(process_resident_memory_bytes[10m])   # mémoire en train de fuir si constamment positif et croissant
promql
# topk / bottomk : les N séries les plus/moins élevées — pratique pour "qui consomme le plus"
topk(5, sum(rate(http_requests_total[5m])) by (path))          # top 5 routes les plus sollicitées
bottomk(3, avg_over_time(up[1h]) by (instance))                  # 3 instances avec la plus mauvaise dispo

# avg_over_time, max_over_time, min_over_time : agrégation sur une fenêtre glissante (pas juste instantané)
avg_over_time(http_request_duration_seconds[1h])
promql
# absent() : détecte l'ABSENCE d'une métrique — essentiel pour alerter "un exporter a disparu"
absent(up{job="mon_api"})
# renvoie 1 si AUCUNE série ne matche (ex: le job a totalement disparu du scraping)

# changes() : nombre de changements de valeur sur la fenêtre (détecte des redémarrages via un counter qui reset)
changes(process_start_time_seconds[1h]) > 0
yaml
# Recording rules : pré-calculer des requêtes coûteuses/fréquentes, exécutées en arrière-plan par Prometheus
# rules/recording_rules.yml
groups:
  - name: api_recording_rules
    interval: 30s
    rules:
      - record: job:http_requests:rate5m           # convention de nommage : niveau:métrique:fonction
        expr: sum(rate(http_requests_total[5m])) by (job)

      - record: job:http_error_rate:ratio5m
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m])) by (job)
          /
          sum(rate(http_requests_total[5m])) by (job)
yaml
# prometheus.yml : brancher les fichiers de règles
rule_files:
  - "rules/recording_rules.yml"
  - "rules/alerting_rules.yml"    # voir leçon Alerting

Résumé

  • group_left/group_right joignent des métriques de cardinalités différentes pour enrichir un résultat avec des labels métier.
  • predict_linear() anticipe une saturation (disque, mémoire) avant qu'elle ne se produise réellement — clé pour l'alerting proactif.
  • topk/bottomk identifient rapidement les séries extrêmes ; absent() détecte la disparition totale d'une métrique/exporter.
  • Les recording rules pré-calculent les requêtes lourdes et répétées (dashboards, alertes) : gain de performance en production à grande échelle.

Exercices pratiques

1 disponible
1

Mission : disque plein dans combien de temps ?

Objectif : Utiliser les fonctions PromQL avancées (predict_linear, absent, topk) pour anticiper une panne et détecter un exporter disparu.

Contexte

L'équipe SRE surveille 30 services. Un disque approche dangereusement de sa capacité, un exporter a disparu du scraping sans que personne ne s'en aperçoive, et personne ne sait quelle route consomme le plus de trafic. Tu dois écrire les requêtes qui répondent à ces trois problèmes distincts.

Résoudre l’exercice →