spinny:~/writing $ less opentelemetry-nodejs-observability-guide.md
12La prima volta che l'osservabilità ti serve davvero non è quando stai guardando una dashboard con calma. È quando un utente scrive "il checkout è lento", il grafico degli errori sembra normale e nei log trovi solo una fila di messaggi scollegati.34OpenTelemetry nasce per evitare quel momento lì: non per avere più grafici, ma per collegare i pezzi. Una richiesta entra nell'API, chiama un database, passa da un provider esterno, pubblica un job in coda e magari fallisce tre servizi dopo. Senza tracing distribuito, quella storia la ricostruisci a mano. Con OpenTelemetry almeno hai una mappa.56## Il punto non sono le trace, è la storia78Una trace è una sequenza di span. Detto così suona freddo. In pratica, ogni span è un pezzo della storia: `POST /checkout`, `SELECT inventory`, `call payment provider`, `publish order.created`.910Il valore arriva quando inizi a rispondere a domande vere:1112- quale servizio esterno sta rallentando?13- gli errori arrivano da una versione specifica?14- il problema riguarda tutti o solo un tenant?15- un retry sta nascondendo un timeout?16- il job asincrono parte ma poi muore da un'altra parte?1718Queste domande non le risolve un `console.log` messo di fretta. Anzi, spesso il log aggiunto in emergenza ti aiuta oggi e diventa rumore domani.1920## Come lo metterei in una app Node.js2122La configurazione più sana è semplice: l'app produce telemetry, il Collector decide dove mandarla.2324```text25Node.js app -> OpenTelemetry Collector -> backend di observability26```2728Perché non esportare direttamente al vendor? Perché all'inizio sembra più veloce, poi ti accorgi che ogni servizio ha configurazioni diverse, retry diversi, filtri diversi e nessun punto centrale dove togliere dati sensibili o cambiare destinazione.2930Il Collector è noioso nel modo giusto. Riceve OTLP, fa batching, può filtrare, può fare sampling, può aggiungere attributi comuni e può esportare verso più sistemi.3132## Auto-instrumentation: bene, ma non basta3334In Node.js partirei con l'auto-instrumentation. Ti dà subito visibilità su HTTP, framework supportati, database e librerie comuni.3536```bash37npm install @opentelemetry/sdk-node \38 @opentelemetry/auto-instrumentations-node \39 @opentelemetry/exporter-trace-otlp-http40```4142Poi inizializzi l'SDK prima del resto dell'app:4344```typescript45import { NodeSDK } from '@opentelemetry/sdk-node';46import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';47import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';4849const sdk = new NodeSDK({50 traceExporter: new OTLPTraceExporter({51 url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,52 }),53 instrumentations: [getNodeAutoInstrumentations()],54});5556sdk.start();57```5859Questo però vede il framework, non il tuo prodotto. Sa che hai fatto una query, ma non sa che quella query era dentro "crea ordine" o "rinnova abbonamento". Per quello servono span manuali nei punti dove il dominio conta.6061```typescript62const span = tracer.startSpan('checkout.create_order');6364try {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```7677Non metterei span manuali ovunque. Li metterei dove, alle tre di notte, vorrei capire cosa è successo senza leggere mezzo codicebase.7879## Tre regole che evitano molto caos8081Prima regola: ogni servizio deve avere `service.name`, ambiente e versione. Sembra banale, ma senza questi attributi una trace è molto meno utile. Quando un deploy rompe qualcosa, vuoi filtrare per versione in due secondi.8283Seconda regola: non mettere dati sensibili negli attributi. Email, token, payload interi e indirizzi non devono finire in un backend di observability per sbaglio. Se ti serve identificare un utente, valuta ID interni, hashing o campi meno delicati.8485Terza regola: attenzione alla cardinalità. `user.id` come attributo di trace può avere senso. Come label di metrica può distruggerti costi e performance.8687## Metriche: poche, ma buone8889Io partirei da metriche molto pratiche:9091- rate, errori e durata delle request;92- latenza delle dipendenze esterne;93- numero di timeout e retry;94- profondità delle code;95- durata dei job;96- percentuale di errori per versione.9798Il resto si aggiunge quando serve. Le dashboard piene di grafici che nessuno guarda sono arredamento, non observability.99100## Log: ancora utili, ma collegati101102I log non spariscono. Semplicemente diventano molto più utili quando portano `trace_id` e `span_id`. Così puoi partire da un log di errore e aprire la trace, oppure partire da una trace lenta e leggere solo i log prodotti in quel percorso.103104Senza correlazione, stai cercando aghi. Con correlazione, almeno sai in quale cassetto guardare.105106## La checklist che userei prima di dire "siamo coperti"107108- Le trace attraversano davvero più servizi.109- I log includono `trace_id` e `span_id`.110- Il Collector è configurato con batching e limiti di memoria.111- Gli errori vengono registrati negli span.112- Esiste una policy di sampling.113- Le metriche hanno cardinalità controllata.114- I dati sensibili vengono filtrati.115- Gli alert partono da sintomi utente, non da grafici casuali.116117## Conclusione118119OpenTelemetry non risolve da solo i problemi di produzione. Però cambia il modo in cui li affronti. Invece di aggiungere log alla cieca, inizi a seguire il percorso reale di una richiesta.120121Per me il segnale che sta funzionando è semplice: quando succede qualcosa, il team smette di chiedere "dove guardiamo?" e inizia a chiedere "perché quel pezzo è lento?". È lì che l'osservabilità diventa uno strumento, non una collezione di dashboard.122123## Fonti124125- [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
:OpenTelemetry in produzione: smettere di debuggare al buiolines 1-129 (END) — press q to close