Aller au contenu

TechniqueDécouverte

L'observabilité en 10 minutes

Pour : ingénieurs et SRE · architectes · managers d’équipe · métiers et produitPrérequis : Aucun. Savoir ce qu'est une application web suffit.

Mode de lecture

Cette page s’adresse à quelqu’un qui découvre le sujet. Elle pose le vocabulaire utilisé partout ailleurs sur le site. Un seul exemple sert de fil rouge : un paiement trop lent sur un site marchand.

Imaginons une boutique en ligne. Le client clique sur « Payer ». D’habitude, la page de confirmation s’affiche en moins d’une seconde. Ce matin, certains clients attendent plusieurs secondes. Quelques-uns abandonnent.

Ce scénario est illustratif. Il est volontairement banal, parce que c’est le genre de problème que l’observabilité doit aider à résoudre.

Derrière le bouton « Payer », plusieurs services travaillent. Un service est un programme qui rend une fonction précise. Ici, un service checkout reçoit la commande. Il appelle un service payment, qui appelle à son tour la banque. Le service checkout lit aussi le panier dans une base de données.

flowchart LR
  C["Client"] --> K["checkout"]
  K --> DB[("Base panier")]
  K --> P["payment"]
  P --> B["API de la banque"]

La question est simple : pourquoi certains paiements sont-ils lents ?

Le monitoring (supervision) surveille des indicateurs choisis à l’avance. On décide par exemple de suivre le taux d’erreur et le temps de réponse. On fixe un seuil. Une alerte part quand le seuil est dépassé.

Le monitoring répond bien aux questions prévues. « Le service est-il disponible ? » « Le temps de réponse dépasse-t-il 2 secondes ? »

Notre problème ne rentre pas dans ces cases. Seuls certains paiements sont lents. Peut-être ceux d’une banque précise, d’un pays ou d’un type de carte. Personne n’avait prévu cette question.

L’observabilité est la capacité à répondre à une question qu’on n’avait pas prévue. On la pose aux données déjà collectées, sans modifier le code ni redéployer. Elle suppose des données riches et reliées entre elles.

Les deux ne s’opposent pas. Le monitoring dit qu’il y a un problème. L’observabilité aide à comprendre lequel.

Un signal est un type de donnée qu’une application émet sur son propre fonctionnement. On parle aussi de télémétrie. Trois signaux sont classiques. Deux autres complètent le tableau.

Une métrique est une mesure numérique, prise à intervalle régulier. Par exemple, le nombre de paiements par minute ou leur durée.

Chaque métrique porte un nom et des labels. Un label est une paire clé et valeur qui précise ce qui est mesuré. Par exemple service="payment" ou status="error".

Les métriques sont compactes et peu coûteuses à garder longtemps. Elles servent aux tableaux de bord et aux alertes. Dans notre exemple, une courbe montre que la durée des paiements a augmenté depuis 9 h. Elle ne dit pas pourquoi.

Une trace raconte le parcours d’une requête à travers tous les services. Elle est faite de spans. Un span est une étape avec un début, une fin et des attributs. Par exemple « appel à la banque, 3,8 secondes ».

Les spans s’emboîtent. Le span du checkout contient celui du payment, qui contient celui de l’appel bancaire. On voit d’un coup d’œil où le temps passe.

POST /checkout (checkout) |=========================================| 4 200 ms
lecture du panier (base) |=| 70 ms
autorisation (payment) |=======================================| 3 950 ms
appel API banque (banque) |=====================================| 3 850 ms

Les durées ci-dessus sont illustratives. La trace montre que le service payment attend la banque. Le problème n’est ni dans la base ni dans le checkout.

Un log (journal) est un message horodaté qui décrit un événement. Par exemple « nouvelle tentative de connexion à la banque, délai dépassé ».

Un log est d’autant plus utile qu’il est structuré, c’est-à-dire écrit sous forme de champs (bank="banque-b", retry=2) plutôt qu’en phrase libre. On peut alors le filtrer et le compter.

Dans notre exemple, les logs du service payment montrent des nouvelles tentatives vers une seule banque. On tient la cause probable.

Un profil mesure où un programme consomme du processeur ou de la mémoire, fonction par fonction. Il répond à la question « quelle ligne de code coûte cher ? ». Dans OpenTelemetry, les profils sont encore en développement (documentation des signaux).

Un événement marque un fait ponctuel qui a du sens pour l’exploitation. Un déploiement, un changement de configuration, une bascule. Superposé à une courbe, il répond à « qu’est-ce qui a changé à 9 h ? ».

SignalQuestion à laquelle il répondDans l’exemple
MétriqueY a-t-il un problème, depuis quand, quelle ampleur ?la durée des paiements monte depuis 9 h
TraceOù, dans quel service, à quelle étape ?le temps passe dans l’appel à la banque
LogQue s’est-il passé exactement ?nouvelles tentatives vers une seule banque
ProfilQuel code consomme les ressources ?utile si le service lui-même était lent
ÉvénementQu’est-ce qui a changé ?un déploiement du service payment à 8 h 55

Pris séparément, chaque signal donne un morceau de l’histoire. L’observabilité commence quand on passe de l’un à l’autre en un clic. Deux mécanismes le permettent.

L’identifiant de trace. Chaque trace reçoit un identifiant unique, le trace id. Il voyage d’un service à l’autre avec la requête, dans un en-tête HTTP standard défini par le W3C (Trace Context). Si les logs portent aussi ce trace id, on passe d’un span lent aux logs exacts de cette requête.

Une métrique peut aussi pointer vers une trace. On appelle ce lien un exemplar : un point de la courbe renvoie vers une requête représentative.

Les attributs de ressource. Une ressource décrit qui émet le signal : le nom du service, sa version, l’environnement, la machine. Si métriques, logs et traces portent les mêmes attributs de ressource, on filtre les trois signaux de la même façon. Par exemple service.name="payment".

flowchart LR
  M["Métrique<br/>durée des paiements"] -->|"exemplar"| T["Trace<br/>appel banque lent"]
  T -->|"trace id"| L["Logs<br/>nouvelles tentatives"]
  M -.->|"service.name"| L

C’est ce que fait OpenTelemetry, le standard ouvert présenté dans OpenTelemetry de bout en bout. Il donne les mêmes identifiants et les mêmes noms d’attributs à tous les signaux.

La cardinalité d’une métrique est le nombre de combinaisons distinctes de ses labels. Chaque combinaison crée une série temporelle, c’est-à-dire une suite de valeurs à stocker (documentation Prometheus). Un label bank avec 20 valeurs et un label status avec 3 valeurs donnent au plus 60 séries. Ajouter un label customer_id avec 100 000 clients multiplie ce nombre par 100 000 (calcul illustratif). Le coût et la lenteur suivent. La règle que je recommande : un identifiant unique (client, commande, requête) va dans les traces et les logs, jamais dans les labels d’une métrique. Le simulateur de cardinalité permet de le vérifier sur vos propres chiffres.

  • OpenTelemetry, Signals : traces, métriques, logs, bagage et statut des profils et des événements.
  • W3C, Trace Context : format de l’en-tête qui transporte l’identifiant de trace.
  • Prometheus, Metric and label naming : chaque combinaison de labels crée une nouvelle série temporelle.