TL;DR. Instrumentez avec OpenTelemetry (standard CNCF, support multi-langage natif). Envoyez les metrics à Prometheus, les logs en structuré JSON vers Loki ou ELK, les traces vers Tempo, Jaeger ou Honeycomb. Évitez les vendor SDKs propriétaires qui vous lockent. Ciblez 3-5 SLO mesurés en production, pas 50 dashboards que personne ne regarde.
Pourquoi observer
L'observabilité, ce n'est pas du monitoring. Le monitoring vérifie que des conditions connuesse réalisent (CPU sous 80 %, disque pas plein, processus up). L'observabilité vous permet de poser des questions inconnues à l'avance sur le comportement de votre système — typiquement quand un client se plaint et que vous ne savez pas pourquoi.
Concrètement, une bonne observabilité vous permet de répondre à trois questions en moins de 5 minutes :
- Quoi ? Quel endpoint, quel service, quel utilisateur est impacté.
- Depuis quand ? Quand exactement le symptôme est apparu, et corréler avec les deploys récents.
- Pourquoi ? Quelle dépendance ou ressource est en cause (DB lente, downstream timeout, fuite mémoire, etc.).
Le triptyque traces / metrics / logs
Les trois piliers de l'observabilité moderne se complètent :
Metrics — la vue agrégée
Une métrique est une mesure numérique agrégée dans le temps : http_requests_total, db_query_duration_seconds, jvm_heap_used_bytes. Coût de stockage très faible, parfait pour les dashboards globaux et les alertes. Limite : pas de granularité fine — vous savez que la p99 latency a augmenté, pas quelle requête.
Logs — la trace ligne par ligne
Un log est un événement discret horodaté.« user 42 logged in », « DB connection failed: timeout after 5s ». Coût de stockage moyen (multiplie par 10 vs metrics), idéal pour le debug ad-hoc et l'audit. Doit être structuré (JSON) pour être exploitable.
Traces — le parcours d'une requête
Une trace suit une requête à travers tous les services qu'elle traverse, avec la durée passée dans chaque span. Coût de stockage le plus élevé (souvent échantillonné), indispensable pour comprendre la latency d'une requête microservices.
OpenTelemetry comme standard d'instrumentation
OpenTelemetry (OTel) est le standard CNCF qui unifie l'instrumentation des trois piliers. Avant OTel, vous instrumentiez votre code avec le SDK Datadog, ou New Relic, ou Dynatrace — et chaque migration coûtait des mois.
Avec OTel, vous instrumentez avec une API standard ; uncollector central exporte ensuite vers le backend de votre choix (Datadog, Grafana Cloud, Honeycomb, Tempo, etc.). Changer de backend = changer la config du collector, pas votre code.
Auto-instrumentation par langage
Java, Python, Node, Go, .NET, Ruby ont tous une auto-instrumentation OTel qui capture sans code les spans HTTP, DB (JDBC, JPA), messaging (Kafka, RabbitMQ), gRPC. Vous l'activez en attachant un agent au démarrage, et 80 % du travail est fait.
Le collector central
L'OpenTelemetry Collector se déploie comme une sidecar Kubernetes ou un DaemonSet. Il reçoit les données via OTLP (le protocole standard), les transforme (sampling, redaction de PII, enrichissement) et les exporte vers le ou les backends choisis. Pattern indispensable pour ne pas locker vos services à un exporter spécifique.
Metrics — Prometheus et au-delà
Prometheus reste l'outil de référence pour les metrics en 2026 — modèle pull, format texte simple, écosystème mature (alertmanager, exporters par technologie). À grande échelle, on remplace le serveur Prometheus seul par :
- VictoriaMetrics : compatible PromQL, beaucoup plus efficient en stockage (compression 10x meilleure), supporte le multi-tenant nativement.
- Mimir (Grafana): architecture distribuée scalable horizontalement, supporte l'ingestion via OTLP en plus du scrape Prometheus.
- Thanos : layer de stockage long-terme pour Prometheus, archive les blocks dans S3.
Les 4 golden signals
Pour chaque service, instrumenter au minimum les 4 golden signals définis par Google SRE :
- Latence — durée des requêtes (avec histogram pour calculer p50/p95/p99).
- Traffic — requêtes par seconde.
- Erreurs— taux d'erreur HTTP 4xx / 5xx.
- Saturation — utilisation des ressources (CPU, mémoire, connexions DB).
Logs structurés
Un log non structuré est une string libre : 2026-06-24 10:00 ERROR user 42 logged in from 1.2.3.4. Pour l'exploiter, il faut parser avec des regex fragiles — chaque changement de format casse vos requêtes.
Un log structuré est un objet JSON avec des champs typés :
{
"ts": "2026-06-24T10:00:00Z",
"level": "ERROR",
"service": "auth",
"user_id": 42,
"tenant_id": "acme",
"event": "login_failed",
"reason": "invalid_password",
"ip": "1.2.3.4",
"trace_id": "abc123..."
}Avantages : indexation native, requêtes par champ, jointures avec les traces via trace_id. Les frameworks modernes (Spring Boot Logback JSON encoder, Pino en Node, structlog en Python) le produisent nativement.
Backends courants
- Elasticsearch / OpenSearch— recherche full-text puissante, dashboards Kibana. Coût d'ops élevé à grande échelle.
- Loki (Grafana) — pensé low-cost (indexe les labels, pas le contenu). Excellent rapport coût/valeur pour les logs applicatifs.
- ClickHouse — option de plus en plus populaire pour les très gros volumes, requêtes SQL natives.
Traces distribuées
Une trace suit une requête à travers les services. Chaque étape est un span, identifié par un trace_id commun + un span_id et un parent_span_id. Quand vous regardez une trace dans Jaeger ou Tempo, vous voyez le waterfall exact :
POST /api/v1/orders [400 ms total] ├── auth.verify_jwt [5 ms] ├── orders.create [380 ms] │ ├── db.insert_order [12 ms] │ ├── kafka.publish_event [3 ms] │ └── payments.charge [360 ms] ← lent ! │ └── stripe.api_call [358 ms] ← cause racine └── response.serialize [2 ms]
Sans trace, vous voyez juste « POST /api/v1/orders a pris 400 ms ». Avec, vous identifiez Stripe comme cause racine en quelques secondes.
Sampling — la question coût
Stocker 100 % des traces coûte cher à l'échelle. Stratégies courantes :
- Head-based— décision à l'entrée (ex. 10 % des requêtes). Simple mais perd les rares requêtes qui échouent.
- Tail-based— décision à la fin (ex. garder toutes les traces avec une erreur ou > 1s). Coûte du buffer dans le collector mais beaucoup plus utile.
Mesurer le ROI après 6 mois
Une bonne observabilité ne se justifie pas par « on a des beaux dashboards ». Mesurez :
- MTTR (Mean Time To Resolve)— temps moyen entre l'incident et la résolution. Cible : réduire de 50 % en 6 mois.
- MTTD (Mean Time To Detect)— temps entre l'apparition du symptôme et la première alerte. Cible : sous 5 minutes pour les pannes critiques.
- Taux d'incidents non détectés — fraction des problèmes signalés par les clientsavant votre monitoring. Cible : sous 10 %.
- SLO atteints — pourcentage du temps où vos Service Level Objectives sont tenus. Cible : publier au moins 3 SLO et viser 99,5 %+.
Pièges classiques
1. La facture Datadog inattendue
Datadog facture les custom metrics au tag — un seul label haute-cardinalité (user_id, tenant_id non bornés) peut multiplier la facture par 100. Toujours tester en preprod avec un dashboard de coût, et instrumenter via OTel pour pouvoir migrer si besoin.
2. 50 dashboards que personne ne regarde
Mieux vaut 3 dashboards utilisés au quotidien (overview production, par service critique, par incident en cours) que 50 dashboards techniques abandonnés. Mesurez les vues dans Grafana pour identifier les dashboards morts.
3. Logs en clair → fuite RGPD
Logger un payload de requête tel quel = logger des PII. Mettez un filtre de redaction dès le départ — c'est beaucoup plus coûteux de re-passer dans 6 mois de logs pour purger.
4. Alertes en boucle
Une alerte qui se déclenche 20 fois par jour est ignorée. Implémentez du alert fatigue management: seuils basés sur des SLO, déduplication, escalation progressive, et un budget d'erreur par service.
En pratique avec Architecture Platform
Notre stack d'observabilité interne (et celle que nous recommandons à nos clients) :
- Instrumentation OTel sur tous les services Java (Spring Boot OTel starter), Node, Python.
- OpenTelemetry Collector en sidecar ECS, qui exporte vers Grafana Cloud (Mimir pour metrics, Loki pour logs, Tempo pour traces).
- Sentry en complément pour les erreurs applicatives front+back (alerting fin sur les releases).
- Trace_id propagé dans tous les logs applicatifs — un seul lien entre la trace Tempo et les logs Loki côté Grafana.
- Audit log signé séparé côté Architecture Platform (pas dans Loki) — exigence SOC 2, durée rétention 7 ans en Enterprise.