Aller au contenu
medium

OpenTelemetry : le standard d'instrumentation universel

18 min de lecture

logo opentelemetry

OpenTelemetry (OTel) est le standard open source qui vous permet d’instrumenter vos applications une seule fois et d’envoyer les données de télémétrie — traces, métriques et logs — vers n’importe quel backend sans modifier votre code. Projet CNCF Graduated au même niveau que Kubernetes, OpenTelemetry fait partie des projets les plus actifs de la fondation (souvent cité comme #2 en velocity derrière Kubernetes). Si vous ne voulez retenir qu’une chose : OpenTelemetry sépare l’instrumentation (comment on collecte) du stockage (où on envoie), et c’est cette séparation qui élimine le vendor lock-in.

  • Le problème avant OTel : vendor lock-in, agents multiples, formats incompatibles
  • Les composants clés : API, SDK, Collector, OTLP — qui fait quoi
  • Les signaux OTel : traces, métriques, logs (et profiles) — état de maturité de chacun
  • Le Collector : pipeline receivers → processors → exporters et patterns de déploiement
  • L’instrumentation : auto-instrumentation (zero-code) vs instrumentation manuelle
  • Les exporters : OTLP et les passerelles vers vos backends existants
  • L’adoption pragmatique : par où commencer dans un système existant

Avant OpenTelemetry, instrumenter une application pour l’observabilité impliquait des choix lourds et coûteux :

Vendor lock-in : chaque plateforme d’observabilité fournissait son propre agent et son propre SDK. Instrumenter pour Datadog signifiait utiliser le SDK Datadog, ses conventions, son format de données. Migrer vers New Relic ou Grafana Cloud nécessitait de ré-instrumenter tout le code.

Agents multiples : un serveur pouvait héberger simultanément un agent Datadog pour les métriques, un agent Jaeger pour les traces, et Fluentd pour les logs. Trois agents, trois configurations, trois consommations de ressources.

Formats incompatibles : les traces Zipkin utilisaient le format B3, Jaeger son propre format, et les métriques passaient par StatsD, Prometheus ou InfluxDB — chacun avec sa sérialisation. Corréler entre ces formats était un cauchemar.

Deux projets concurrents : en 2019, la communauté avait deux projets d’instrumentation ouverte — OpenTracing (tracing API) et OpenCensus (tracing + métriques, initié par Google). Les deux faisaient presque la même chose, fragmentant l’écosystème et les contributions.

En mai 2019, OpenTracing et OpenCensus ont fusionné pour créer OpenTelemetry, sous l’égide de la CNCF (Cloud Native Computing Foundation). L’objectif : un standard unique d’instrumentation, neutre vis-à-vis des vendors, couvrant tous les signaux.

OpenTelemetry n’est pas un outil unique — c’est un écosystème de composants qui se combinent. Chaque composant a un rôle précis :

L’API OpenTelemetry est un ensemble d’interfaces (pas d’implémentation) qui définissent comment créer des spans, enregistrer des métriques, émettre des logs. Elle est conçue pour être stable et rétrocompatible : votre code applicatif dépend de l’API, jamais directement du SDK.

Pourquoi cette séparation ? Les bibliothèques partagées (frameworks HTTP, clients de base de données, ORMs) peuvent s’instrumenter avec l’API OpenTelemetry sans imposer de dépendance lourde à leurs utilisateurs. Si l’application n’a pas configuré de SDK, les appels à l’API sont des no-ops (pas d’impact sur les performances).

Le SDK est l’implémentation concrète de l’API, spécifique à chaque langage (Java, Python, Go, .NET, JavaScript, Rust…). C’est le SDK qui :

  • Crée réellement les spans et les points de données
  • Gère le sampling (head-based, probability-based)
  • Configure les exporters (où envoyer les données)
  • Gère le batching et le buffering avant export
  • Injecte le contexte dans les logs (bridge logging)

Le SDK est configuré au démarrage de l’application (pas dans le code métier). Vous pouvez changer d’exporter ou de sampling sans modifier une seule ligne de code applicatif.

OTLP (OpenTelemetry Protocol) est le protocole natif pour transporter les données de télémétrie. Il supporte les trois signaux (traces, métriques, logs) dans un format unique, avec deux modes de transport :

ModePort conventionnelUsage
gRPC4317Haute performance, streaming, production
HTTP/protobuf4318Compatibilité large, traverse les proxies HTTP

Ces ports sont une convention largement adoptée, pas une obligation protocolaire — adaptez-les selon votre réseau ou votre service mesh.

OTLP est le format recommandé pour la communication SDK → Collector et Collector → backend. La plupart des backends modernes le supportent nativement (Tempo, Jaeger, Prometheus remote write, Elastic APM, Datadog, New Relic).

Le Collector est un composant autonome, écrit en Go, qui reçoit, traite et exporte les données de télémétrie. C’est le routeur de votre infrastructure d’observabilité.

Le Collector sera détaillé dans la section suivante — c’est le composant le plus important à comprendre pour le déploiement.

OpenTelemetry couvre aujourd’hui quatre signaux. Leur niveau de maturité détermine ce que vous pouvez utiliser en production en toute confiance :

SignalMaturitéDétail
TracesStable (GA depuis 2021)Signal le plus mature — API, SDK, Collector, OTLP : tout est stable dans les langages majeurs
MétriquesStable (GA depuis 2023)API et SDK stables dans la plupart des langages — support OTLP, histogrammes exponentiels, exemplars
LogsStable (GA depuis 2023)Le Logs Bridge API permet d’injecter le contexte OTel dans vos frameworks de logging existants — le niveau de stabilité varie encore selon le langage/SDK
ProfilesEn développement4ᵉ signal (profiling continu — CPU, mémoire, allocations). Spécification en cours, pas encore prêt pour la production

Le Collector : pipeline receive → process → export

Section intitulée « Le Collector : pipeline receive → process → export »

Le Collector est le composant qui découple vos applications de vos backends. Il se configure via un fichier YAML organisé en quatre sections :

Pipeline OpenTelemetry Collector : Receivers → Processors → Exporters

  • Receivers : points d’entrée — comment les données arrivent au Collector (OTLP, scrape Prometheus, fichiers de logs, protocoles legacy)
  • Processors : transformations en vol — batching, limitation mémoire, filtrage, enrichissement d’attributs, sampling
  • Exporters : points de sortie — vers quels backends envoyer les données

Une quatrième section, Extensions, gère les fonctionnalités transverses (health check, pprof, zpages pour le debug).

receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
http:
endpoint: "0.0.0.0:4318"
processors:
batch:
send_batch_size: 1024
timeout: 5s
memory_limiter:
check_interval: 1s
limit_mib: 2048
spike_limit_mib: 512
exporters:
otlp/tempo:
endpoint: "tempo:4317"
tls:
insecure: true
prometheus:
endpoint: "0.0.0.0:8889"
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/tempo]
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [prometheus]
logs:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [loki]

Ce fichier déclare trois pipelines — un par signal — qui reçoivent les données via OTLP (gRPC et HTTP), appliquent un memory limiter et du batching, puis exportent vers Tempo (traces), Prometheus (métriques) et Loki (logs).

Le Collector peut être déployé de trois façons, selon vos besoins :

PatternDescriptionCas d’usage
SidecarUn Collector par pod/conteneur, colocalisé avec l’applicationIsolation forte, faible latence d’export, overhead par pod
Agent (DaemonSet)Un Collector par nœud du clusterBon compromis performance/ressources, collecte des logs système
GatewayUn pool centralisé de Collectors en aval des agentsTail-based sampling, enrichissement centralisé, routage multi-backend

En pratique, les architectures combinent souvent agent + gateway : un agent DaemonSet collecte et pré-traite localement, puis envoie au gateway qui applique le sampling intelligent et route vers les backends.

OpenTelemetry propose deux approches complémentaires pour instrumenter vos applications :

L’auto-instrumentation intercepte automatiquement les appels aux bibliothèques connues (clients HTTP, clients de base de données, frameworks web) et crée des spans sans que vous modifiiez votre code applicatif.

Selon le langage, le mécanisme est différent :

LangageMécanismeComment l’activer
JavaAgent Java (javaagent JAR)-javaagent:opentelemetry-javaagent.jar au démarrage de la JVM
PythonMonkey-patching via opentelemetry-instrumentopentelemetry-instrument python app.py
.NETAgent .NET ou variables d’environnementVariables OTEL_DOTNET_AUTO_*
Node.jsModule loader (--require)node --require @opentelemetry/auto-instrumentations-node app.js
GoPas d’agent classique (pas de VM)Instrumentation manuelle le plus souvent ; des approches eBPF / OBI (OpenTelemetry eBPF Instrumentation) émergent pour certains scénarios

Avantages : déploiement rapide, pas de modification du code source, couvre les frameworks les plus courants.

Limites : ne capture que les opérations des bibliothèques connues — pas le contexte métier (ID commande, montant, utilisateur). Les spans créés sont génériques.

L’instrumentation manuelle utilise l’API OpenTelemetry pour créer des spans et des attributs spécifiques à votre logique métier :

from opentelemetry import trace
tracer = trace.get_tracer("payment-service")
def process_payment(order_id: str, amount: float):
with tracer.start_as_current_span("process_payment") as span:
span.set_attribute("order.id", order_id)
span.set_attribute("order.amount", amount)
# ... logique de paiement

Avantages : contrôle total sur les spans, attributs métier riches, nommage significatif.

Limites : nécessite de modifier le code source, maintenance à prévoir.

  1. Commencez par l’auto-instrumentation

    Activez l’auto-instrumentation pour obtenir immédiatement les spans des appels HTTP, des requêtes SQL, des appels gRPC — sans modifier le code.

  2. Ajoutez l’instrumentation manuelle où ça compte

    Sur les opérations métier critiques (paiement, création de commande, authentification), ajoutez des spans manuels avec des attributs métier pertinents pour le diagnostic.

  3. Ne sur-instrumentez pas

    Chaque span a un coût (CPU, mémoire, réseau). Instrumentez les opérations qui aident au diagnostic — pas chaque fonction interne.

Le SDK et le Collector peuvent exporter les données vers de nombreux backends. OTLP est le format natif, mais des exporters spécifiques existent pour les systèmes qui ne supportent pas (encore) OTLP :

BackendProtocoleTracesMétriquesLogs
TempoOTLP (natif)Oui
JaegerOTLP (natif)Oui
PrometheusRemote Write / ScrapeOui
LokiPush APIOui
ElasticsearchAPI ElasticsearchOuiOuiOui
DatadogAPI DatadogOuiOuiOui
New RelicOTLP (natif)OuiOuiOui
Grafana CloudOTLP (natif)OuiOuiOui

Adopter OpenTelemetry dans un système existant ne se fait pas en un jour. Voici une stratégie progressive qui minimise les risques :

  1. Commencez par les traces

    C’est le signal le plus mature et celui qui apporte le plus de valeur immédiate dans une architecture distribuée. Activez l’auto-instrumentation sur un ou deux services critiques, déployez un Collector en mode agent, et envoyez vers Tempo ou Jaeger.

  2. Ajoutez la corrélation logs ↔ traces

    Configurez le Logs Bridge pour injecter le trace_id dans vos logs existants. Vous obtenez la navigation log → trace sans changer de logger.

  3. Migrez les métriques progressivement

    Si vous utilisez déjà Prometheus, continuez à le scraper directement. Le Collector peut aussi scraper vos targets Prometheus (receiver prometheus) et ajouter des exemplars OTLP. La migration peut être graduelle.

  4. Déployez un gateway pour le sampling intelligent

    Quand le volume de traces devient coûteux, ajoutez un Collector en mode gateway avec du tail-based sampling pour capturer 100 % des erreurs et échantillonner le trafic normal.

PiègePourquoi c’est un problèmeSolution
Dépendre directement du SDK dans le code métierCouplage fort, migration difficileDépendre uniquement de l’API dans le code applicatif ; configurer le SDK au démarrage
Envoyer directement au backend sans CollectorPas de batching, pas de retry, pas de buffer en cas de panne backendToujours interposer un Collector entre l’application et le backend
Utiliser la distribution Core en productionIl manque les exporters vers vos backends spécifiquesUtiliser la distribution Contrib ou construire un Collector custom avec ocb
Oublier le memory_limiter dans le CollectorLe Collector consomme de la mémoire sans limite → OOM killToujours configurer memory_limiter comme premier processor de chaque pipeline
Sur-instrumenterTrop de spans = coût élevé + bruit dans les tracesInstrumenter les opérations utiles au diagnostic, pas chaque ligne de code
Confondre auto-instrumentation et visibilité complèteL’auto-instrumentation ne capture pas le contexte métierCompléter avec de l’instrumentation manuelle sur les opérations critiques
  1. OpenTelemetry sépare l’instrumentation du stockage — vous instrumentez une fois avec l’API/SDK, et vous routez vers n’importe quel backend via le Collector

  2. Les quatre composants : API (contrat stable), SDK (implémentation par langage), OTLP (protocole de transport), Collector (pipeline receive → process → export)

  3. Les trois signaux sont largement stables : traces (GA 2021), métriques (GA 2023), logs (GA 2023) — mais la maturité varie selon le langage/SDK. Les profiles arrivent en 4ᵉ signal

  4. Le Collector est le routeur central — receivers pour les entrées, processors pour les transformations, exporters pour les sorties. Configuration YAML, déploiement en agent, sidecar ou gateway

  5. Auto-instrumentation + instrumentation manuelle se combinent : zero-code pour la couverture de base, manuelle pour le contexte métier

  6. Adoptez progressivement : traces d’abord sur 1-2 services, puis corrélation logs, puis métriques — ne pas tout instrumenter d’un coup

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.