Aller au contenu
Outils medium

Instrumentation

15 min de lecture

L'instrumentation est la première étape du pipeline d'observabilité : c'est le code qui génère les signaux, métriques, logs, traces, au sein même de vos applications. Un backend ne peut afficher que ce que l'instrumentation a émis : une trace sans service.name reste anonyme quel que soit le tableau de bord placé derrière.

Mais "instrumenter" n'est pas un seul outil. C'est un empilement de couches qui vont de votre code jusqu'au backend. Cette page vous explique comment ces briques s'assemblent.

Lisez le schéma de haut en bas, dans le sens de circulation des signaux. Chaque couche a un point de configuration distinct, et c'est ce qui compte pour vous : un problème de nommage de service se règle dans le SDK, un problème de volume dans le sampling, un problème de données sensibles dans le Collector. Savoir à quelle couche appartient un symptôme évite de modifier le code applicatif pour un réglage qui vit ailleurs.

Couches d'instrumentation : du code applicatif aux backends

Plus vous descendez dans le pipeline, plus la configuration est centralisée et donc facile à gouverner, mais plus vous perdez le contexte métier : le Collector voit passer des spans, il ne sait pas qu'il s'agit d'un abandon de panier.

L'API fournit une interface stable dans le code : tracer, meter, logger. Votre code appelle ces primitives sans savoir quel backend stockera les données.

OutilCe qu'il fait
OpenTelemetry APIInterface standard pour traces, métriques, logs (multi-langage)
Micrometer (Java)Facade "metrics-first" très utilisée dans l'écosystème Spring

Dans le code, ça ressemble à :

# Créer un span (trace)
with tracer.start_as_current_span("checkout.process") as span:
span.set_attribute("cart.items", 3)
# ... logique métier
// Incrémenter un compteur (métrique)
counter.add(1, Attributes.of(stringKey("status"), "success"));

2. SDK : l'implémentation qui collecte et exporte

Section intitulée « 2. SDK : l'implémentation qui collecte et exporte »

Le SDK transforme ce que produit l'API en télémétrie exploitable :

ResponsabilitéCe que ça fait
Buffering / BatchRegroupe les signaux avant export (économise le réseau)
RetryRé-essaie en cas d'échec réseau
SamplingDécide quelles traces garder (ratio, parent-based...)
PropagationInjecte/extrait le contexte (trace-id) entre services
ExportEnvoie les signaux vers OTLP (ou autre format)

C'est dans le SDK que vous configurez :

Fenêtre de terminal
# Identité du service
OTEL_SERVICE_NAME=checkout-api
OTEL_RESOURCE_ATTRIBUTES=service.version=1.2.3,deployment.environment=production
# Export OTLP vers le Collector
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
# Sampling (10% des traces)
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1

L'auto-instrumentation intercepte automatiquement les appels aux frameworks et librairies (HTTP, DB, messaging) sans modifier votre code.

LangageComment ça marche
JavaAgent JVM : -javaagent:opentelemetry-javaagent.jar
PythonWrapper : opentelemetry-instrument python app.py
Node.jsRequire : --require @opentelemetry/auto-instrumentations-node/register
.NETRuntime hooks (variable CORECLR_ENABLE_PROFILING)
GoInstrumentation des packages (net/http, database/sql...)
PHPExtension PHP : opentelemetry.so

Quand l'utiliser ?

  • Pour couvrir rapidement 80% des spans (HTTP entrant/sortant, SQL, Redis, Kafka...)
  • Sur du legacy où vous ne voulez pas toucher le code
  • En complément de spans manuels pour la logique métier

4. Exporters : comment les signaux sortent de l'application

Section intitulée « 4. Exporters : comment les signaux sortent de l'application »

L'exporter envoie les signaux vers une destination. En 2026, le standard est :

App (SDK) → OTLP → Collector

Pourquoi OTLP vers un Collector (et pas directement vers le backend) ?

AvantageExplication
DécouplageVotre app ne "connaît" qu'un endpoint OTLP
FlexibilitéChangez de backend (Jaeger → Tempo) sans recoder
GouvernanceFiltrage, redaction, routing centralisés
RésilienceLe Collector bufferise si le backend est down

Le Collector est le routeur central de votre télémétrie. Il reçoit les signaux OTLP et les transforme/route vers vos backends.

Ce qu'il fait :

FonctionExemple
NormaliserConvertir différents formats en un seul
EnrichirAjouter metadata Kubernetes (namespace, pod, node)
FiltrerExclure les healthchecks, les routes internes
RedacterMasquer les tokens, emails, données sensibles
RouterTraces → Tempo, Métriques → Mimir, Logs → Loki
BufferiserQueue + retry si backend indisponible

La colonne « Où ça vit » est celle à retenir, parce qu'elle dit qui doit intervenir quand un réglage change. Modifier l'API ou les spans manuels implique un développeur et un redéploiement. Modifier le SDK se fait par variables d'environnement, donc au niveau du déploiement. Modifier le Collector ne touche aucune application. Cette progression est exactement ce qui rend l'architecture avec Collector plus soutenable dans la durée.

CoucheExempleOù ça vitÀ quoi ça sert
API / FacadeOTel API, MicrometerDans le codeInterface stable, appels de l'app
SDKOTel SDK Java/Python/NodeDans le runtimeCollecte, batching, sampling, export
Auto-instrumentationJava Agent, Python distroAutour de l'appSpans/metrics automatiques sans toucher le code
ExporterOTLP exporterDans l'appSortie des signaux
CollectorOTel CollectorInfraGouvernance, routing, résilience

Chaque environnement a ses contraintes. Voici les trois patterns les plus courants :

L'application exporte directement vers le backend, sans intermédiaire. C'est la configuration la plus courte à écrire, et la seule dette qu'elle crée est l'adresse du backend inscrite dans la configuration de chaque service. Sur un seul service, ce n'est rien. Sur quinze, chaque changement de backend devient une campagne de redéploiement.

  • Avantage : simple, rapide à mettre en place
  • Limite : couplé au backend, difficile à faire évoluer
  • Limite : pas de gouvernance centralisée

Quand l'utiliser : POC, application standalone, environnement de développement.

Toutes les applications exportent vers un Collector central qui route vers les backends. La configuration applicative se réduit alors à une seule adresse OTLP, identique pour tous les services, et tout ce qui relève du filtrage, du masquage ou du routage sort du code.

Architecture standard avec Collector central

  • Avantage : découplage entre les applications et les backends
  • Avantage : gouvernance centralisée (filtrage, masquage, sampling)
  • Avantage : plusieurs backends sans modifier le code applicatif

Quand l'utiliser : dès que vous avez plusieurs services en production.

Chaque node a un agent (DaemonSet) qui collecte localement, puis envoie à un gateway central. Ce dédoublement répond à deux besoins que le Collector unique ne couvre pas : l'agent est le seul à pouvoir lire les métadonnées du node et les journaux des conteneurs qui y tournent, et il absorbe les pics locaux sans saturer le réseau inter-node.

Architecture Kubernetes agent + gateway

  • Avantage : collecte locale, donc faible latence réseau
  • Avantage : enrichissement Kubernetes (namespace, pod, node)
  • Avantage : routage centralisé et haute disponibilité par réplication du gateway

Quand l'utiliser : clusters Kubernetes de production, multi-tenants, équipes plateforme.

Ce tableau se lit par le besoin, pas par l'outil. Deux lignes se combinent presque toujours en production : l'auto-instrumentation couvre les appels techniques, les spans manuels ajoutent le contexte métier que rien d'automatique ne peut deviner. Choisir l'une contre l'autre est une erreur fréquente ; elles ne répondent pas à la même question.

Vous voulez...Solution
Zéro codeAuto-instrumentation + OTLP → Collector
Du contexte métierSpans manuels via API + SDK
Découpler du backendOTLP exporter vers Collector
Standardiser cross-langageOpenTelemetry partout
Juste des métriques JVMMicrometer (mais OTel reste compatible)
Migrer du legacyOTel Shim pour OpenTracing/OpenCensus

Avant de tout tracer, instrumentez l'essentiel :

Les six étapes sont ordonnées par dépendance, pas par importance. Les deux premières conditionnent tout le reste : sans identité de service, vos traces arrivent anonymes dans le backend, et sans propagation W3C, chaque service crée sa propre trace au lieu de continuer celle de l'appelant, ce qui donne des traces coupées en morceaux que rien ne relie.

ÉtapeCe qu'il faut faire
1. IdentitéOTEL_SERVICE_NAME, service.version, deployment.environment
2. PropagationW3C Trace Context (traceparent) activé
3. Spans métier3-5 opérations clés (checkout, paiement, génération PDF)
4. Métriques REDRate, Errors, Duration (p50/p95/p99)
5. RedactionMasquer tokens, emails, PII avant export
6. SamplingRatio 10-20% pour commencer, affiner ensuite

Ces variables sont standardisées par la spécification OpenTelemetry : elles portent le même nom quel que soit le langage, ce qui permet de les injecter uniformément depuis un manifeste Kubernetes ou un fichier docker compose. Le port 4317 correspond au transport gRPC ; passez à 4318 si vous exportez en HTTP.

Fenêtre de terminal
# Identité du service
OTEL_SERVICE_NAME=checkout-api
OTEL_RESOURCE_ATTRIBUTES=service.version=1.2.3,deployment.environment=production
# Export OTLP
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
# Sampling (ajuster selon le volume)
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1

La première ligne du tableau est celle qui coûte le plus cher en facture. Mettre un identifiant unique (identifiant de commande, adresse e-mail, identifiant de session) dans un label de métrique crée une série temporelle distincte par valeur : quelques milliers de commandes suffisent à faire exploser la cardinalité et à saturer le backend. Les identifiants ont leur place dans les attributs de span, pas dans les métriques.

Anti-patternConséquenceSolution
IDs uniques en tags/labelsExplosion cardinalité, coûtsUtiliser des catégories (status, region)
Tout tracer sans samplingOverhead perf, coûts stockageRatio 10-20% puis tail-based
Spans trop verbeuxBruit, difficile à exploiter5-10 attributs max par span
Pas de validation localeBugs découverts en prodExporter vers console/debug en dev
Ignorer service.nameTraces anonymes, inutilisablesToujours définir l'identité
Exporter direct vers backendCouplage, pas de gouvernancePasser par le Collector

OpenTelemetry est le seul projet à couvrir les trois signaux (traces, métriques, logs) avec une API commune et des conventions de nommage partagées. C'est par ce guide qu'il faut commencer, les autres pages de cette section supposent son vocabulaire acquis.

Chaque langage a son mécanisme d'injection, résumé dans le tableau plus haut : agent JVM pour Java, exécutable d'enrobage pour Python, chargement de module au démarrage pour Node.js. Les guides détaillés par langage restent à écrire ; en attendant, la page OpenTelemetry ci-dessus couvre les concepts communs à tous.

Guides prévus : OpenTelemetry Java Agent, Python, Node.js, et l'Operator K8s.

Micrometer précède OpenTelemetry dans l'écosystème Spring et reste très présent sur les applications Java existantes. Il ne couvre que les métriques, mais il sait exporter en OTLP, ce qui permet de le conserver côté code tout en unifiant la sortie avec le reste de votre télémétrie.

Cette page décrit l'assemblage des couches. Pour aller plus loin, deux directions : les fondamentaux OpenTelemetry si le modèle de données (signal, contexte, propagation) n'est pas encore clair, ou le guide du Collector si votre instrumentation fonctionne et que vous voulez maintenant filtrer, enrichir et router ce qu'elle produit.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn