spinny:~/writing $ vim opentelemetry-nodejs-observability-guide.md
1~2La première fois que vous avez vraiment besoin d’observabilité, ce n’est pas lorsque vous regardez calmement un tableau de bord. C'est lorsqu'un utilisateur écrit « le paiement est lent », que le graphique d'erreur semble normal et que dans les journaux, vous ne trouvez qu'une rangée de messages déconnectés.3~4OpenTelemetry a été créé pour éviter ce moment : non pas pour avoir plus de graphiques, mais pour relier les pièces. Une requête entre dans le API, appelle une base de données, passe par un fournisseur externe, publie une tâche en file d'attente et peut échouer trois services plus tard. Sans traçage distribué, vous reconstruisez cette histoire à la main. Avec OpenTelemetry au moins vous avez une carte.5~6## Le problème n'est pas le trace, c'est l'histoire7~8Un trace est une séquence de span. Dit comme ça, ça fait froid. En pratique, chaque span est un morceau de l'histoire : `POST /checkout`, `SELECT inventory`, `call payment provider`, `publish order.created`.9~10La valeur vient lorsque vous commencez à répondre à de vraies questions :11~12- quel service externe ralentit ?13- les erreurs proviennent-elles d'une version spécifique ?14- le problème concerne-t-il tout le monde ou un seul locataire ?15- une nouvelle tentative cache-t-elle un délai d'attente ?16- le travail asynchrone démarre mais meurt ensuite ailleurs ?17~18Ces questions ne peuvent pas être résolues par un `console.log` lancé à la hâte. En effet, souvent le journal ajouté en cas d'urgence vous aide aujourd'hui et devient du bruit demain.19~20## Comment pourrais-je mettre cela dans une application Node.js21~22La configuration la plus saine est simple : l'application produit la télémétrie, le Collector décide où l'envoyer.23~24```text25Node.js app -> OpenTelemetry Collector -> backend di observability26```27~28Pourquoi ne pas exporter directement vers le fournisseur ? Parce qu'au début, cela semble plus rapide, vous réalisez ensuite que chaque service a des configurations différentes, des tentatives différentes, des filtres différents et aucun point central pour supprimer les données sensibles ou changer de destination.29~30Le Collector est ennuyeux dans tous les sens du terme. Il reçoit OTLP, effectue le traitement par lots, peut filtrer, effectuer des échantillonnages, ajouter des attributs communs et exporter vers plusieurs systèmes.31~32## Auto-instrumentation : bien, mais pas suffisant33~34En Node.js, je commencerais par l'auto-instrumentation. Il vous offre une visibilité immédiate sur HTTP, les frameworks pris en charge, les bases de données et les bibliothèques communes.35~36```bash37npm install @opentelemetry/sdk-node \38 @opentelemetry/auto-instrumentations-node \39 @opentelemetry/exporter-trace-otlp-http40```41~42Ensuite, vous initialisez le SDK avant le reste de l'application :43~44```typescript45import { NodeSDK } from '@opentelemetry/sdk-node';46import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';47import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';48~49const sdk = new NodeSDK({50 traceExporter: new OTLPTraceExporter({51 url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,52 }),53 instrumentations: [getNodeAutoInstrumentations()],54});55~56sdk.start();57```58~59Cependant, cela concerne le cadre, pas votre produit. Il sait que vous avez effectué une requête, mais il ne sait pas que cette requête était dans « ordre de création » ou « renouvellement d'abonnement ». Pour cela, vous avez besoin de span manuels aux points où la domination compte.60~61```typescript62const span = tracer.startSpan('checkout.create_order');63~64try {65 span.setAttribute('cart.items_count', input.items.length);66 const order = await createOrder(input);67 span.setAttribute('order.id', order.id);68 return order;69} catch (error) {70 span.recordException(error as Error);71 throw error;72} finally {73 span.end();74}75```76~77Je ne mettrais les manuels span nulle part. Je les mettrais là où, à trois heures du matin, j'aimerais comprendre ce qui s'est passé sans lire la moitié de la base de code.78~79## Trois règles qui évitent beaucoup de chaos80~81Première règle : chaque service doit avoir `service.name`, environnement et version. Cela semble trivial, mais sans ces attributs, un trace est beaucoup moins utile. Lorsqu'un déploiement interrompt quelque chose, vous souhaitez filtrer par version en deux secondes.82~83Deuxième règle : ne mettez pas de données sensibles dans les attributs. Les e-mails, les jetons, les charges utiles entières et les adresses ne doivent pas se retrouver par accident dans un backend d’observabilité. Si vous devez identifier un utilisateur, envisagez les identifiants internes, le hachage ou les champs moins sensibles.84~85Troisième règle : faites attention à la cardinalité. `user.id` comme attribut de trace peut avoir du sens. En tant qu'étiquette métrique, elle peut détruire vos coûts et vos performances.86~87## Métriques : peu nombreuses, mais bonnes88~89Je commencerais par des mesures très pratiques :90~91- tarifs, erreurs et durée des demandes ;92- latence des dépendances externes ;93- nombre de délais d'attente et de tentatives ;94- profondeur des queues ;95- durée du travail ;96- pourcentage d'erreurs par version.97~98Le reste est ajouté en cas de besoin. Les tableaux de bord remplis de graphiques que personne ne regarde sont des meubles, pas des observables.99~100## Logs : toujours utiles, mais liés101~102Les journaux ne disparaissent pas. Ils deviennent simplement beaucoup plus utiles lorsqu'ils portent `trace_id` et `span_id`. Vous pouvez donc partir d'un journal d'erreurs et ouvrir le trace, ou partir d'un trace lent et lire uniquement les journaux produits dans ce chemin.103~104Sans corrélation, vous recherchez des aiguilles. Avec la corrélation, au moins vous savez dans quel tiroir regarder.105~106## La checklist que j'utiliserais avant de dire "nous sommes couverts"107~108- Le trace traverse en fait plusieurs services.109- Les journaux incluent `trace_id` et `span_id`.110- Le Collector est configuré avec des limites de traitement par lots et de mémoire.111- Les erreurs sont enregistrées en span.112- Il existe une politique d'échantillonnage.113- Les métriques ont une cardinalité contrôlée.114- Les données sensibles sont filtrées.115- Les alertes partent des symptômes de l'utilisateur et non de graphiques aléatoires.116~117## Conclusion118~119OpenTelemetry ne résout pas à lui seul les problèmes de production. Mais la façon dont vous les gérez change. Au lieu d'ajouter aveuglément des journaux, vous commencez à suivre le chemin réel d'une requête.120~121Pour moi, le signe que ça marche est simple : quand quelque chose arrive, l'équipe arrête de se demander « où cherche-t-on ? et commence à demander "pourquoi ce morceau est-il lent ?". C'est là que l'observabilité devient un outil et non un ensemble de tableaux de bord.122~123##Sources124~125- [OpenTelemetry: Overview](https://opentelemetry.io/docs/specs/otel/overview/)126- [OpenTelemetry Collector: Configuration](https://opentelemetry.io/docs/collector/configuration/)127- [OpenTelemetry JavaScript: Node.js getting started](https://opentelemetry.io/docs/languages/js/getting-started/nodejs/)128- [OpenTelemetry Semantic Conventions](https://opentelemetry.io/docs/concepts/semantic-conventions/)129~
NORMAL · opentelemetry-nodejs-observability-guide.md [readonly]129 lines · :q to close