Observabilité moderne avec OpenTelemetry et Grafana
J’ai longtemps utilisé la stack ELK et Prometheus + Grafana séparément. Puis j’ai découvert OpenTelemetry. Voici pourquoi j’ai migré et comment j’ai intégré le tout avec Grafana.
Le problème que je rencontrais était celui de la dispersion : mes logs allaient dans ELK, mes métriques dans Prometheus, mes traces dans un outil tiers. Chaque service devait donc être instrumenté de façon différente selon l’outil, et corréler un log avec une trace ou une métrique demandait de jongler entre plusieurs interfaces. OpenTelemetry m’a offert un moyen d’unifier tout ça.
OpenTelemetry, c’est quoi ?
OpenTelemetry (OTel) est un standard ouvert pour collecter et exporter des traces, métriques et logs (les trois piliers de l’observabilité). Un seul agent, un seul format, direction votre backend préféré.
L’idée centrale est qu’OTel ne fournit ni du stockage ni de la visualisation : il ne fait que collecter et transporter les données observées dans un format standard. C’est ce qui le rend interopérable : les mêmes données instrumentées une fois peuvent être acheminées vers Grafana, Jaeger, Datadog ou n’importe quel backend compatible.
Avant OTel, chaque service devait être instrumenté pour chaque backend :
Service A → Prometheus (métriques) + Jaeger (traces) + ELK (logs) |
Avec OTel :
Service A → OTel SDK → Collector → Grafana (métriques) + Tempo (traces) + Loki (logs) |
Le changement est radical : Service A et Service B utilisent le même kit d’instrumentation, quelle que soit la destination. Si on change de backend (passer de Prometheus à un SaaS, par exemple), on ne retouche pas les services : seul le Collector change de configuration d’export.
Architecture type
Deux niveaux se distinguent dans ce schéma. Chaque application embarque un OTel SDK qui capture les données de son processus. Puis tout converge vers le Collector, qui reçoit ces données, peut les transformer (ajouter des métadonnées, filtrer, échantillonner) et les achemine vers les backends. Le Collector est le point d’intégration unique : c’est lui qu’on configure, jamais chaque service.
Instrumenter une app Node.js
npm install @opentelemetry/api @opentelemetry/sdk-node \ |
const { NodeSDK } = require('@opentelemetry/sdk-node'); |
C’est tout. Les traces HTTP, les requêtes DB, les calls externes sont automatiquement capturés.
Le point fort est la boîte à outils getNodeAutoInstrumentations() : elle détecte les bibliothèques populaires (Express, les clients HTTP, les drivers de base de données, etc.) et les instrumente automatiquement grâce à des wrappers. Vous n’avez pas à écrire d’instrumentation manuelle pour les cas courants : les traces des requêtes HTTP entrantes, des appels sortants et des accès DB sont générées par défaut.
OTel Collector
Le collector est le cœur du pipeline. Il reçoit, transforme et achemine les données.
receivers: |
La configuration se lit aisément comme un pipeline. Les receivers définissent où entrent les données (ici OTLP sur gRPC et HTTP). Les processors transforment : le batch regroupe les données pour optimiser les envois réseau, le memory_limiter protège le Collector d’une surcharge mémoire. Les exporters définissent la destination. Enfin, la section pipelines relit le tout : les traces entrent par OTLP, passent par batch, et sortent vers Tempo ; les métriques vers Prometheus ; les logs vers Loki.
Le batch mérite une mention : sans lui, chaque petit bout de données partirait immédiatement, provoquant une pluie de requêtes réseau peu chargées. En les accumulant avant envoi, on réduit nettement la charge réseau tout en augmentant le débit effectif.
Grafana : tout en un
Avec Grafana, plus besoin de changer de dashboard :
- Prometheus pour les métriques (CPU, RAM, latence)
- Tempo pour les traces distribuées
- Loki pour les logs
Et la killer feature : Tempo peut retrouver les traces à partir des logs Loki, grâce aux trace IDs automatiquement injectés par OTel.
C’est là que l’approche unifiée paie. Dans Grafana, vous avez un seul endroit pour voir les métriques d’un service, plonger dans ses logs, et suivre une requête individuelle à travers tous les services. Et grâce aux trace IDs propagés par OTel dans les logs, un clic sur un log vous amène directement à la trace correspondante : vous voyez, en contexte, toutes les opérations que cette requête a déclenchées.
Ce que ça change au quotidien
- Debug : une requête lente identifiée en 2 clics au lieu de 30 min
- Alerting : une métrique + une trace = un contexte complet
- Coût : OTel est open source, pas de licence par nœud
Un exemple vécu : une anomalie de latence sur une API. Avant, j’aurais cherché dans les logs, essayé de corréler avec les métriques, puis reconstruit manuellement le parcours d’une requête. Avec OTel + Tempo, je vois directement la requête lente dans la liste des traces, un clic sur sa flame graph, et j’identifie en quelques secondes que c’est l’appel à tel service tiers qui explose. Le bottleneck qui me prenait une demi-heure se voit en deux clics.
La stack OTel + Grafana est devenue mon réflexe pour tout nouveau projet. Le surcoût d’installation est vite rentabilisé quand vous passez de 2h à 5 min pour identifier un goulot d’étranglement.
Et comme le format est standard, cette investissement ne vous verrouille à aucun éditeur : si vos besoins évoluent, le Collector redirige vos données vers un autre backend sans toucher une ligne à vos services.