Jour 15 Day 15 · mercredi 19 août 2026 Wednesday 19 August 2026 DevOps Intermédiaire

Observabilité : logs, metrics & traces Observability: logs, metrics & traces

Les trois piliers, Prometheus, OpenTelemetry, SLO : savoir expliquer comment on debugge un système en prod — la question qui sépare ceux qui ont déployé de ceux qui ont juste codé. The three pillars, Prometheus, OpenTelemetry, SLOs: knowing how to explain debugging a production system — the question that separates those who have deployed from those who have only coded.

L’essentiel

Le monitoring répond à des questions connues d’avance : « le CPU dépasse-t-il 80 % ? », « le service répond-il ? ». On définit des seuils, on affiche des dashboards, on alerte. L’observabilité va plus loin : c’est la capacité à répondre à des questions qu’on n’avait pas anticipées — « pourquoi les requêtes des utilisateurs premium sur ce endpoint sont-elles lentes depuis le déploiement de 14h ? » — à partir des données que le système émet (ses outputs), sans redéployer du code instrumenté à la main.

La distinction vient du monde des systèmes distribués : avec un monolithe, on SSH sur le serveur et on lit les logs. Avec 15 services derrière un load balancer, une requête traverse 6 services — savoir que c’est lent (monitoring) ne dit pas où ni pourquoi (observabilité).

En entretien de stage, le sujet fait la différence parce qu’il révèle si le candidat a déjà exploité une application, pas seulement écrit du code : celui qui a cherché un bug en prod à 2 requêtes/seconde de logs non structurés comprend immédiatement pourquoi tout ça existe.

Comment ça marche

L’observabilité repose sur trois piliers complémentaires :

Les logs — des événements horodatés et discrets : « telle requête a échoué avec telle erreur ». La règle moderne : des logs structurés en JSON plutôt que du texte libre — on peut alors filtrer, agréger, chercher par champ :

{
  "timestamp": "2026-08-10T14:03:07Z",
  "level": "error",       // filtrable par champ
  "route": "/checkout",
  "duration_ms": 870,     // agrégeable (p99 par route)
  "user_id": 42,          // le contexte qui manque à un printf
  // le même ID que dans la trace → corrélation entre piliers
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "msg": "payment provider timeout"
}

Indispensable : cet identifiant de corrélation (request ID, trace ID), propagé de service en service, permet de reconstituer le parcours d’une requête à travers les logs de toute la stack.

Les metrics — des valeurs numériques agrégées dans le temps : compteurs, jauges, histogrammes. Peu coûteuses à stocker, parfaites pour les dashboards et les alertes. Deux grilles de lecture classiques : RED pour les services (Rate : requêtes/s, Errors : taux d’erreur, Duration : latence — en percentiles p50/p95/p99, jamais en moyenne) et USE pour les ressources (Utilization, Saturation, Errors). Une metric dit qu’il y a un problème, rarement lequel.

Les traces — le parcours d’une requête individuelle à travers les services. Une trace est un arbre de spans : chaque span représente une opération (appel HTTP, requête SQL) avec début, durée, attributs et parent. La magie s’appelle context propagation : le trace ID et le span ID parent voyagent dans les headers HTTP (standard W3C traceparent) d’un service à l’autre, ce qui permet de reconstituer l’arbre complet :

trace 4bf92f… — GET /checkout — 800 ms
├─ gateway          [■■■■■■■■■■■■■■■■■■■■] 800 ms
│  ├─ svc panier    [■■■]                  150 ms
│  └─ svc paiement      [■■■■■■■■■■■■■■■]  620 ms
│     └─ SQL UPDATE      [■■■■■■■■■■■■■■]  600 ms ◀ ici
└─ chaque ligne = un span (début, durée, parent)

D’un coup d’œil : sur 800 ms de latence, 600 sont dans une requête SQL du service paiement.

Les trois piliers en un coup d’œil :

LogsMetricsTraces
NatureÉvénements discrets, riches en contexteAgrégats numériques dans le tempsParcours d’une requête, en spans
CoûtÉlevé (facturé au Go ingéré)FaibleMoyen (échantillonné)
Répond à« Que s’est-il passé exactement ? »« Ça va mal ? Où, depuis quand ? »« Où est passé le temps ? »

La stack type qu’un candidat doit savoir citer : Prometheus (metrics, modèle pull : il scrappe un endpoint /metrics, avec son langage de requête PromQL) + Grafana (dashboards) ; Loki ou la stack ELK (Elasticsearch/Logstash/Kibana) pour les logs ; Jaeger ou Tempo pour les traces. Et au-dessus de tout : OpenTelemetry (OTel), le standard vendor-neutral de la CNCF qui unifie l’instrumentation — SDK par langage, souvent de l’auto-instrumentation, un Collector qui reçoit, transforme et exporte vers le backend de son choix. On instrumente une fois, on change de backend sans toucher au code : c’est l’argument clé.

🎤 En entretien — le déroulé qui marque : metrics pour détecter (le p99 monte), traces pour localiser (quel span porte la latence), logs pour expliquer (quelle erreur), le tout relié par le trace ID. Cette chaîne récitée calmement vaut mieux que dix noms d’outils.

Concepts clés à maîtriser

  • Corrélation entre piliers : le vrai pouvoir vient du lien — une alerte metric (p99 en hausse) → les traces lentes de la période → les logs des spans en erreur, reliés par le trace ID. Les trois piliers isolés font trois silos ; corrélés, un outil de diagnostic.
  • Cardinality et coûts : chaque combinaison de labels d’une metric crée une série temporelle distincte (voir le piège plus bas) ; côté logs, le volume se paie au Go ingéré, d’où l’échantillonnage (sampling) des traces en production.
  • SLI/SLO : un SLI est une mesure de ce que vivent les utilisateurs (ex. « proportion de requêtes servies en moins de 300 ms »), un SLO l’objectif qu’on s’engage à tenir dessus (ex. 99,9 % sur 30 jours). Le budget d’erreur qui en découle arbitre entre fiabilité et vélocité de déploiement.

💡 Alerter sur les symptômes, pas les causes — on réveille quelqu’un pour ce que les utilisateurs subissent (taux d’erreur, latence — les SLI), jamais pour un CPU à 95 % avec des utilisateurs heureux. Un taux d’erreur à 5 % mérite une alerte quelle qu’en soit la cause ; les causes se consultent dans les dashboards après l’alerte.

En entretien

« Quelle différence entre monitoring et observabilité ? » — Le monitoring vérifie des conditions connues d’avance (seuils, dashboards prédéfinis) ; l’observabilité permet d’interroger le système sur des problèmes non anticipés, grâce à des données riches (logs structurés, traces, metrics) émises par le système. Formule qui marque : le monitoring dit que ça casse, l’observabilité permet de comprendre pourquoi.

« Explique les trois piliers. » — dérouler le tableau plus haut, puis conclure sur la corrélation via trace ID : c’est elle qui transforme trois outils en un système.

« Comment debuggerais-tu une API soudainement lente en prod ? » — Dashboard RED : la latence p99 monte — sur quel endpoint, depuis quand, corrélé à un déploiement ? Traces des requêtes lentes : quel span porte la latence (SQL ? appel externe ? le service lui-même ?). Logs corrélés par trace ID pour le détail (le déroulé du callout plus haut).

« C’est quoi OpenTelemetry et pourquoi c’est devenu le standard ? » — Un projet CNCF qui standardise la génération et l’export des trois signaux : API/SDK par langage, context propagation, Collector. Vendor-neutral : on instrumente une fois et on exporte vers Jaeger, Prometheus, Datadog ou autre — pas de lock-in par l’instrumentation. C’est devenu le socle commun de tout l’écosystème.

« Pourquoi regarder le p99 plutôt que la latence moyenne ? » — La moyenne cache la distribution : 99 requêtes à 50 ms + 1 à 5 s = moyenne correcte, expérience désastreuse pour 1 % des utilisateurs — souvent les plus actifs (plus de requêtes = plus de chances de toucher la queue de distribution). Les percentiles décrivent ce que vivent réellement les utilisateurs.

Pièges & idées reçues

⚠️ Cardinality explosion — chaque combinaison de valeurs de labels crée une série temporelle : un label user_id sur un compteur Prometheus = des millions de séries = mémoire qui explose. Labels à valeurs bornées (status code, endpoint, région) ; les identifiants uniques vont dans les logs et les traces.

  • Logger sans contexte : un console.log("error") sans request ID, sans user ID, sans champ structuré est illisible à 100 req/s. Log structuré + corrélation, sinon c’est du bruit.
  • L’alert fatigue : des alertes qui crient en permanence (seuils trop fins, alertes sur les causes) finissent ignorées — et le jour où c’est grave, personne ne regarde. Chaque alerte doit être actionnable ; une alerte qu’on acquitte sans agir doit être supprimée ou revue.
  • Les dashboards que personne ne regarde : accumuler 40 dashboards n’est pas de l’observabilité. Quelques vues orientées symptômes (RED par service) consultées pendant les incidents valent mieux qu’un mur d’écrans décoratif.
  • « On ajoutera l’observabilité plus tard » : instrumenter après l’incident, c’est trop tard. L’auto-instrumentation OTel rend le coût initial faible — l’excuse ne tient plus.
  • Tout tracer à 100 % en prod : le volume coûte cher pour une valeur marginale ; on échantillonne (head/tail sampling) en gardant systématiquement les traces en erreur et les plus lentes.

Pour aller plus loin

The essentials

Monitoring answers questions known in advance: “is CPU above 80%?”, “is the service responding?”. You define thresholds, display dashboards, alert. Observability goes further: it’s the ability to answer questions you hadn’t anticipated — “why are premium users’ requests on this endpoint slow since the 2pm deploy?” — from the data the system emits (its outputs), without redeploying hand-instrumented code.

The distinction comes from the world of distributed systems: with a monolith, you SSH into the server and read the logs. With 15 services behind a load balancer, a request crosses 6 services — knowing that it’s slow (monitoring) doesn’t tell you where or why (observability).

In an internship interview, this topic makes the difference because it reveals whether the candidate has actually operated an application, not just written code: anyone who has hunted a production bug through 2 requests/second of unstructured logs immediately understands why all of this exists.

How it works

Observability rests on three complementary pillars:

Logs — discrete, timestamped events: “this request failed with this error”. The modern rule: structured JSON logs rather than free text — you can then filter, aggregate, and search by field:

{
  "timestamp": "2026-08-10T14:03:07Z",
  "level": "error",       // filterable by field
  "route": "/checkout",
  "duration_ms": 870,     // aggregatable (p99 per route)
  "user_id": 42,          // the context a printf lacks
  // the same ID as in the trace → cross-pillar correlation
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "msg": "payment provider timeout"
}

Essential: this correlation identifier (request ID, trace ID), propagated from service to service, lets you reconstruct a request’s journey through the logs of the whole stack.

Metrics — numeric values aggregated over time: counters, gauges, histograms. Cheap to store, perfect for dashboards and alerts. Two classic reading grids: RED for services (Rate: requests/s, Errors: error rate, Duration: latency — in p50/p95/p99 percentiles, never averages) and USE for resources (Utilization, Saturation, Errors). A metric says there is a problem, rarely which one.

Traces — the journey of an individual request through the services. A trace is a tree of spans: each span represents one operation (HTTP call, SQL query) with a start, a duration, attributes and a parent. The magic is called context propagation: the trace ID and parent span ID travel in HTTP headers (the W3C traceparent standard) from service to service, allowing the full tree to be reconstructed:

trace 4bf92f… — GET /checkout — 800 ms
├─ gateway          [■■■■■■■■■■■■■■■■■■■■] 800 ms
│  ├─ cart svc      [■■■]                  150 ms
│  └─ payment svc       [■■■■■■■■■■■■■■■]  620 ms
│     └─ SQL UPDATE      [■■■■■■■■■■■■■■]  600 ms ◀ here
└─ each line = one span (start, duration, parent)

At a glance: out of 800 ms of latency, 600 sit in a SQL query in the payment service.

The three pillars at a glance:

LogsMetricsTraces
NatureDiscrete events, rich in contextNumeric aggregates over timeOne request’s journey, in spans
CostHigh (billed per GB ingested)LowMedium (sampled)
Answers“What exactly happened?”“Is something wrong? Where, since when?”“Where did the time go?”

The typical stack a candidate should be able to cite: Prometheus (metrics, pull model: it scrapes a /metrics endpoint, with its PromQL query language) + Grafana (dashboards); Loki or the ELK stack (Elasticsearch/Logstash/Kibana) for logs; Jaeger or Tempo for traces. And above it all: OpenTelemetry (OTel), the CNCF’s vendor-neutral standard unifying instrumentation — per-language SDKs, often auto-instrumentation, a Collector that receives, transforms and exports to the backend of your choice. Instrument once, switch backends without touching the code: that’s the key argument.

🎤 In an interview — the walkthrough that lands: metrics to detect (p99 is up), traces to locate (which span carries the latency), logs to explain (which error), all tied together by the trace ID. Reciting that chain calmly beats dropping ten tool names.

Key concepts to master

  • Correlation across pillars: the real power comes from the link — a metric alert (rising p99) → the slow traces of that period → the logs of the failing spans, tied together by the trace ID. The three pillars in isolation are three silos; correlated, they’re a diagnostic tool.
  • Cardinality and cost: every combination of a metric’s label values creates a distinct time series (see the pitfall below); on the log side, volume is billed per GB ingested, hence trace sampling in production.
  • SLI/SLO: an SLI is a measurement of what users experience (e.g. “proportion of requests served under 300 ms”), an SLO is the target you commit to on it (e.g. 99.9% over 30 days). The resulting error budget arbitrates between reliability and deployment velocity.

💡 Alert on symptoms, not causes — you wake someone up for what users suffer (error rate, latency — the SLIs), never for a CPU at 95% with happy users. A 5% error rate deserves an alert whatever the cause; causes get consulted in dashboards after the alert fires.

In an interview

“What’s the difference between monitoring and observability?” — Monitoring checks conditions known in advance (thresholds, predefined dashboards); observability lets you interrogate the system about unanticipated problems, thanks to rich data (structured logs, traces, metrics) the system emits. A line that lands: monitoring tells you that it’s broken, observability lets you understand why.

“Explain the three pillars.” — walk through the table above, then close on correlation via trace ID: that’s what turns three tools into one system.

“How would you debug an API that suddenly got slow in production?” — RED dashboard: p99 latency is up — on which endpoint, since when, correlated with a deploy? Traces of the slow requests: which span carries the latency (SQL? external call? the service itself?). Logs correlated by trace ID for the detail (the walkthrough from the callout above).

“What is OpenTelemetry and why did it become the standard?” — A CNCF project standardizing the generation and export of the three signals: per-language API/SDK, context propagation, the Collector. Vendor-neutral: instrument once and export to Jaeger, Prometheus, Datadog or anything else — no lock-in through instrumentation. It has become the common foundation of the whole ecosystem.

“Why look at p99 rather than average latency?” — The average hides the distribution: 99 requests at 50 ms + 1 at 5 s = a decent average, a disastrous experience for 1% of users — often the most active ones (more requests = more chances of hitting the tail). Percentiles describe what users actually experience.

Pitfalls & misconceptions

⚠️ Cardinality explosion — every combination of label values creates a time series: a user_id label on a Prometheus counter = millions of series = memory blowing up. Labels with bounded values only (status code, endpoint, region); unique identifiers belong in logs and traces.

  • Logging without context: a console.log("error") with no request ID, no user ID, no structured field is unreadable at 100 req/s. Structured logging + correlation, otherwise it’s noise.
  • Alert fatigue: alerts that scream constantly (thresholds too tight, alerts on causes) end up ignored — and the day it’s serious, nobody looks. Every alert must be actionable; an alert you acknowledge without acting on should be deleted or reworked.
  • Dashboards nobody looks at: piling up 40 dashboards is not observability. A few symptom-oriented views (RED per service) consulted during incidents beat a decorative wall of screens.
  • “We’ll add observability later”: instrumenting after the incident is too late. OTel auto-instrumentation makes the initial cost low — the excuse no longer holds.
  • Tracing 100% in production: the volume costs a lot for marginal value; you sample (head/tail sampling) while always keeping errored and slowest traces.

Going further

S'entraîner sur ce sujet → Practice this topic →