Aller au contenu
medium

Les métriques : le signal compact et rapide

21 min de lecture

Votre dashboard affiche “CPU à 87 %”. Un graphe montre le taux de requêtes HTTP en hausse depuis une heure. Un autre indique que le p99 de latence a doublé. Ces trois informations sont des métriques — des valeurs numériques, agrégées dans le temps, qui permettent de voir l’état de vos systèmes en un coup d’œil. Là où un log raconte l’histoire individuelle de chaque événement, une métrique résume des milliers d’événements en un seul chiffre exploitable instantanément.

  • Qu’est-ce qu’une métrique : valeur numérique + nom + labels + timestamp
  • Les 4 types : counter, gauge, histogram, summary — quand utiliser chacun
  • Labels et cardinalité : pourquoi un label user_id peut faire tomber votre monitoring
  • Conventions de nommage : suffixes _total, _seconds, _bytes et pourquoi elles comptent
  • Pull vs Push : deux modèles de collecte et leurs compromis
  • Agrégation : ce qui rend les métriques si puissantes (et si différentes des logs)

Une métrique est un triplet : un nom, un ensemble de labels et une valeur numérique, le tout associé à un timestamp.

http_requests_total{method="GET", status="200", service="checkout-api"} 142857

Décomposons :

ComposantRôleExemple
NomIdentifie ce qu’on mesurehttp_requests_total
LabelsDimensionnent la métrique (paires clé/valeur)method="GET", status="200"
ValeurLe chiffre mesuré142857
TimestampQuand la mesure a été prise(implicite, ajouté à la collecte)

Chaque combinaison unique nom + labels forme une série temporelle (time series). C’est cette série qui est stockée, requêtée et affichée sur un graphe.

Le tableau de bord d’une voiture est un système de métriques :

  • Le compteur kilométrique ne fait que monter — c’est un counter.
  • L’indicateur de vitesse monte et descend en temps réel — c’est un gauge.
  • La répartition des trajets par durée (combien de trajets de 0-10 min, 10-30 min, 30+ min) — c’est un histogram.

Le conducteur ne lit pas le journal de chaque tour de roue (ce serait un log). Il lit les agrégats : vitesse actuelle, distance parcourue, consommation moyenne. C’est exactement ce que font les métriques pour vos systèmes.

CaractéristiqueMétriqueLog
NatureValeur numérique agrégéeÉvénement discret textuel
VolumeFaible (ordre de grandeur : bien plus compact que des logs)Élevé (100-1000 octets par ligne)
Coût de stockageFaibleÉlevé
AlertingNatif et rapide (seuil sur un chiffre)Lent (requête textuelle)
Diagnostic root causeLimité (pas de contexte individuel)Excellent (détail de chaque événement)
Réponse à”Combien ?”, “À quelle vitesse ?”, “Quelle tendance ?""Que s’est-il passé exactement ?”

Les métriques vous alertent qu’il y a un problème. Les logs vous expliquent lequel.

Les systèmes de monitoring modernes (Prometheus, OpenTelemetry, StatsD) distinguent 4 types fondamentaux de métriques. Chacun répond à un besoin précis. Choisir le mauvais type revient à mesurer la température avec un compteur kilométrique.

Un counter est un compteur monotone croissant : il ne fait que monter (ou revenir à zéro quand le processus redémarre). On ne regarde jamais sa valeur brute — on calcule son taux de variation dans le temps.

Quand l’utiliser : tout ce qui s’accumule de façon irréversible.

ExempleNom de métrique
Nombre total de requêtes HTTPhttp_requests_total
Nombre d’erreurshttp_errors_total
Octets envoyés sur le réseaunode_network_transmit_bytes_total
Redémarrages d’un conteneurkube_pod_container_status_restarts_total

Ce qu’on en tire : le taux par seconde. “Combien de requêtes par seconde mon service traite-t-il en ce moment ?” s’obtient en calculant la variation du counter sur un intervalle :

Concept : rate(http_requests_total, sur 5 minutes)
→ "en moyenne, X requêtes/seconde sur les 5 dernières minutes"

Un gauge est une valeur qui monte et descend librement. Il représente un état instantané, une “photo” à un instant donné.

Quand l’utiliser : tout ce qui reflète un état courant.

ExempleNom de métrique
Mémoire disponiblenode_memory_MemAvailable_bytes
Nombre de goroutines activesgo_goroutines
Température du CPUnode_hwmon_temp_celsius
Taille de la file d’attentequeue_length

Ce qu’on en tire : la valeur courante, les min/max, les tendances. “La file d’attente est-elle en train de grossir ?” → on regarde le gauge au fil du temps.

Un gauge peut baisser autant que monter. C’est ce qui le distingue fondamentalement d’un counter.

Un histogram mesure la distribution des valeurs observées en les répartissant dans des buckets (intervalles) prédéfinis. Il est conçu pour répondre à la question : “Quel pourcentage de mes requêtes prennent moins de 300 ms ?”

Quand l’utiliser : latence, taille de requête, durée d’opération — tout ce qui a une distribution avec des percentiles intéressants.

ExempleNom de métrique
Durée des requêtes HTTPhttp_request_duration_seconds
Taille des réponseshttp_response_size_bytes

Comment ça marche : vous définissez des seuils (buckets), par exemple : 0,01s, 0,05s, 0,1s, 0,25s, 0,5s, 1s, 5s. L’histogram incrémente le compteur de chaque bucket où la valeur observée “rentre”. Une requête de 0,3s incrémente les buckets 0,5s, 1s et 5s (tous les buckets supérieurs ou égaux à la valeur).

Le système stocke en réalité 3 séries par histogram :

  • _bucket{le="0.5"} : nombre d’observations ≤ 0,5 s
  • _sum : somme de toutes les valeurs observées
  • _count : nombre total d’observations

À partir de ces données, on peut calculer des percentiles (p50, p95, p99) côté serveur, sans connaître chaque valeur individuelle. En Prometheus, vous requêtez ..._bucket, ..._sum et ..._count — le nom racine (http_request_duration_seconds) est une famille de séries, pas une série unique.

Un summary ressemble à un histogram, mais les percentiles sont calculés côté client (dans l’application) au lieu du côté serveur.

CritèreHistogramSummary
Calcul des percentilesCôté serveur (à la requête)Côté client (dans l’application)
Agrégation entre instancesPossible (sum des buckets)Impossible (les percentiles ne s’agrègent pas)
PrécisionApproximation (dépend des buckets)Plus directe (côté client), dépend de l’implémentation
Coût en séries temporelles1 série par bucket1 série par quantile
RecommandationPréféré dans la plupart des casSi vous savez exactement quels quantiles vous voulez, et que vous n’avez pas besoin d’agréger

En pratique : préférez les histograms. Ils sont agrégables (on peut additionner les buckets de 10 instances pour obtenir un percentile global), alors que les summaries ne le sont pas. Si vous avez 10 pods et que chacun calcule son p99 localement, la moyenne de ces 10 p99 n’est pas le p99 global.

Labels et cardinalité : la puissance et le piège

Section intitulée « Labels et cardinalité : la puissance et le piège »

Les labels sont ce qui rend les métriques dimensionnelles. Une seule métrique http_requests_total peut être déclinée par méthode, par code de status, par service, par route — sans créer une nouvelle métrique pour chaque combinaison.

http_requests_total{method="GET", status="200", service="checkout"} 89421
http_requests_total{method="POST", status="201", service="checkout"} 12303
http_requests_total{method="GET", status="500", service="checkout"} 147

Chaque combinaison unique de labels crée une série temporelle distincte. Et c’est là que le piège se referme.

La cardinalité d’une métrique est le nombre total de séries temporelles qu’elle génère. Elle se calcule par multiplication :

cardinalité = valeurs_label_1 × valeurs_label_2 × … × valeurs_label_N

Exemple sain : http_requests_total avec method (5 valeurs) × status (10 valeurs) × service (8 valeurs) = 5 × 10 × 8 = 400 séries. Gérable.

Exemple dangereux : la même métrique avec un label user_id (100 000 utilisateurs) = 5 × 10 × 8 × 100 000 = 40 millions de séries. Votre TSDB (base de données de séries temporelles) va saturer en mémoire, les requêtes vont expirer, et l’alerting va cesser de fonctionner.

N’utilisez jamais ces valeurs comme labels :

Label dangereuxPourquoiAlternative
user_idCardinalité = nombre d’utilisateursLogger (pas une métrique)
request_id / trace_idCardinalité infinieAppartient aux logs/traces
email, ip_addressCardinalité très élevée + PIINe pas instrumenter
URL complète (/users/12345/profile)Cardinalité = nombre de routes × IDsNormaliser en route : /users/{id}/profile
Timestamp dans un labelCardinalité infinieDéjà le timestamp de la série
Message d’erreur completCardinalité = nombre de messages distinctsUtiliser error_type (10-20 valeurs)
exception / stacktrace brutsCardinalité = nombre de stack traces distinctesCatégoriser par type d’exception (TimeoutError, ValidationError)

Un bon label a un nombre de valeurs faible et prévisible :

LabelValeurs typiquesCardinalité
methodGET, POST, PUT, DELETE, PATCH5
status200, 201, 301, 400, 401, 403, 404, 500, 502, 503~10
serviceNoms de vos microservices5-50
environmentproduction, staging, dev3
regioneu-west-1, us-east-1…3-10

Règle d’or : si un label peut avoir plus de quelques centaines de valeurs, il ne devrait probablement pas être un label de métrique. L’information détaillée appartient aux logs ou aux traces.

Des noms cohérents rendent les métriques compréhensibles sans documentation. Prometheus a établi des conventions qui sont devenues le standard de facto, reprises par OpenTelemetry.

<namespace>_<nom>_<unité>_<suffixe_type>
PartieRôleExemples
namespaceDomaine ou applicationhttp, node, process, kube
nomCe qu’on mesurerequests, cpu_seconds, memory
unitéUnité de mesure (au pluriel)seconds, bytes, celsius
suffixe typeIndique le type de métrique_total (counter), _info (labels statiques)
NomTypeCe qu’il mesure
http_requests_totalcounterNombre cumulé de requêtes HTTP
http_request_duration_secondshistogramDistribution des durées de requêtes
node_memory_MemAvailable_bytesgaugeMémoire disponible en octets
process_cpu_seconds_totalcounterTemps CPU consommé par le processus
node_disk_io_time_seconds_totalcounterTemps passé en I/O disque
kube_pod_container_status_restarts_totalcounterRedémarrages de conteneur
RègleExemple correctContre-exemple
Unité en suffixe, au pluriel_seconds, _bytes_ms, _b, _byte
Unités de base (pas de milli, micro)_seconds (valeur 0.003)_milliseconds (valeur 3)
Counter → suffixe _totalhttp_errors_totalhttp_errors
snake_case, pas de camelCasehttp_request_durationhttpRequestDuration
Pas de type dans le nomhttp_request_duration_secondshttp_request_duration_seconds_histogram

Les métriques doivent être acheminées de l’application vers le backend de stockage. Deux philosophies coexistent.

Le serveur de monitoring interroge les applications à intervalle régulier (par défaut 15-30 secondes). Chaque application expose un endpoint HTTP (typiquement /metrics) qui renvoie toutes ses métriques au format texte.

Prometheus ──(scrape toutes les 15s)──► /metrics de checkout-api
Prometheus ──(scrape toutes les 15s)──► /metrics de payment-api
Prometheus ──(scrape toutes les 15s)──► /metrics de user-api

Avantages :

  • Le serveur de monitoring contrôle le rythme de collecte.
  • Si une cible ne répond plus, c’est détecté immédiatement (scrape failed → alerte “target down”).
  • Pas besoin de configurer chaque application pour qu’elle sache où envoyer ses métriques.

Limites :

  • Moins adapté aux jobs éphémères (un job batch de 10 secondes peut terminer entre deux scrapes). Prometheus propose le Pushgateway pour ce cas — mais uniquement pour les batch jobs, pas comme bus de métriques générique.
  • Nécessite que le serveur de monitoring puisse joindre chaque cible sur le réseau.

L’application envoie ses métriques vers un collecteur ou un backend à chaque intervalle ou à chaque événement.

checkout-api ──(push toutes les 10s)──► Collecteur / Backend
payment-api ──(push toutes les 10s)──► Collecteur / Backend

Avantages :

  • Fonctionne derrière des pare-feu ou NAT (c’est l’application qui initie la connexion sortante).
  • Naturel pour les jobs courts ou les fonctions serverless.
  • Le protocole OTLP (OpenTelemetry) est push-first et unifie métriques, logs et traces.

Limites :

  • Pas de détection native de “target down” (si l’application plante, elle arrête d’envoyer — mais personne ne le sait tant qu’une alerte sur l’absence de données n’est pas configurée).
  • L’application doit connaître l’adresse du collecteur.
CritèrePull (Prometheus)Push (OTLP, StatsD)
Jobs long-runningIdéalFonctionne
Jobs éphémères / serverlessVia PushgatewayNatif
Détection de cible downAutomatiqueAlerter sur l’absence de données
Réseaux restreints (NAT, pare-feu)Complexe (besoin d’accès entrant)Simple (connexion sortante)
Standard émergentDominant aujourd’huiOTLP (OpenTelemetry) tend à s’imposer

En pratique, beaucoup d’architectures combinent les deux : Prometheus scrape les services internes (pull), et un OpenTelemetry Collector reçoit les données push des sources externes ou éphémères.

Ce qui rend les métriques fondamentalement différentes des logs, c’est leur capacité à être agrégées mathématiquement. On peut additionner, moyenner, calculer des taux et des percentiles — sans manipuler les événements individuels.

OpérationCe qu’elle faitExemple conceptuel
Rate (taux)Calcule la vitesse de variation d’un counter par seconde”Le compteur de requêtes augmente de 142/s en moyenne sur les 5 dernières minutes”
Increase (augmentation)Combien un counter a augmenté sur une période”Il y a eu 42 600 requêtes dans la dernière heure”
Quantile / PercentileCalcule un seuil de distribution à partir d’un histogram”99 % des requêtes prennent moins de 350 ms (p99 = 350 ms)“

Imaginez un service qui traite 10 000 requêtes par seconde. En une heure, c’est 36 millions d’événements. Si chaque événement est un log, vous avez 36 millions de lignes à stocker et à fouiller.

Avec des métriques, ces 36 millions d’événements se résument à quelques séries temporelles : un counter pour le nombre de requêtes, un histogram pour la latence, un gauge pour les connexions actives. Le tout occupe quelques kilo-octets par intervalle de scrape.

C’est ce compromis — perdre le détail individuel mais gagner en vitesse, en coût et en capacité d’alerting — qui fait des métriques le signal de premier recours pour la surveillance opérationnelle. Les SLI/SLO sont d’ailleurs des métriques agrégées orientées utilisateur (taux d’erreur, latence sous seuil) — c’est l’agrégation qui permet de transformer des millions de requêtes en un seul chiffre de fiabilité.

Ces trois patterns couvrent l’essentiel du requêtage quotidien :

# Taux d'événements/s à partir d'un counter
sum(rate(http_requests_total[5m]))
# Volume sur une période à partir d'un counter
sum(increase(http_requests_total[1h]))
# p99 à partir d'un histogram
histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

Un dashboard en production affiche des agrégats (par service, par route, par méthode), pas des séries par pod ou par instance. Si votre graphe superpose 200 lignes, vous avez oublié d’agréger.

PiègePourquoi c’est un problèmeQue faire
Label user_id ou request_idExplosion de cardinalité → OOM du TSDBCes infos appartiennent aux logs/traces
Afficher la valeur brute d’un counterLe chiffre 4 237 891 ne veut rien dire seulToujours afficher le rate() ou increase()
Noms de métriques sans unitérequest_duration → secondes ? millisecondes ?Toujours inclure l’unité : _seconds, _bytes
Trop de buckets dans un histogramChaque bucket crée une série temporelle supplémentaire10-15 buckets suffisent, alignés sur le SLO
Métriques non agrégées dans les dashboardsGraphe illisible avec 200 séries superposéesAgréger par service, par route — jamais par pod/instance
Utiliser un summary quand on a besoin d’agrégerLes percentiles de summaries ne s’additionnent pas entre instancesPréférer les histograms
  • Une métrique est un triplet (nom + labels + valeur numérique) horodaté. C’est le signal le plus compact, le moins cher à stocker et le plus rapide à requêter.

  • Il existe 4 types : le counter (compteur qui ne fait que monter), le gauge (valeur instantanée), l’histogram (distribution en buckets) et le summary (percentiles côté client).

  • Les labels dimensionnent une métrique (méthode, status, service) mais chaque combinaison crée une série temporelle. Un label à haute cardinalité (user_id) peut faire tomber tout le monitoring.

  • Les conventions de nommage (_total, _seconds, _bytes, snake_case) rendent les métriques auto-documentées.

  • Pull (Prometheus scrape) et Push (OTLP, StatsD) sont deux modèles complémentaires. La tendance va vers OTLP (push) comme standard unifié.

  • L’agrégation (rate, increase, percentile) est ce qui distingue les métriques des logs : on résume des millions d’événements en quelques chiffres exploitables.

  • Les métriques vous alertent qu’il y a un problème. Les logs et les traces vous expliquent lequel.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.