OpenTelemetry

OpenTelemetry: guida pratica all'osservabilità moderna 🔭

L’osservabilità è la risposta alla domanda: «posso capire cosa sta succedendo in produzione senza attaccare un debugger al vivo e senza indovinare?». Se la risposta è “ni”, allora ti serve questo articolo.

Observability vs monitoring 🧭

Spesso usati come sinonimi, non lo sono. Una sintesi brutalmente onesta:

Aspetto Monitoring Observability
Domanda principale “Funziona?” “Perché si comporta così?”
Dati tipici Metriche note (CPU, error_rate) Dati grezzi ricchi + correlazione
Modello mentale Dashboard + soglie Esplorazione + domande ad‐hoc
Reazione Notifica → runbook Indagine → comprensione → miglioramento
Dipendenza da ipotesi iniziali Alta Minore (domande emergenti)

Il monitoring ti dice che stai perdendo sangue. L’observability ti aiuta a scoprire dove e perché.

Quanto profonda debba essere l’osservabilità dipende dagli SLO operativi, spesso derivati da SLA contrattuali: senza SLO chiari si rischiano telemetrie ridondanti e costi eccessivi; con SLO ben definiti si misura solo ciò che serve a rispettare gli impegni.

A cosa serve l’osservabilità 🎯

L’osservabilità non è un vezzo estetico per avere dashboard piene di colori: è la leva operativa che fa la differenza tra reagire nel panico o governare un sistema complesso con lucidità. Un sistema davvero osservabile permette di porre domande nuove senza aver previsto prima ogni singolo contatore.

In pratica ti consente di:

  • Ridurre il MTTR (Mean Time To Recovery) perché passi meno tempo a formulare ipotesi sbagliate e più tempo a intervenire sul punto preciso del degrado.
  • Prevenire regressioni: quando attivi un feature flag o fai un canary release puoi osservare l’effetto reale su latenza, errori e conversioni anziché affidarti a sensazioni.
  • Correlare esperienza utente e infrastruttura: capire che l’aumento dei carrelli abbandonati coincide con la latenza del servizio pricing in eu-west-1 dopo un autoscaling lento.
  • Individuare colli di bottiglia e leak prima che diventino incidenti notturni: una coda che cresce lentamente, un pool che non rilascia risorse, una query che peggiora settimanalmente.
  • Supportare capacity planning con dati di trend e saturazione storica invece di extrapolazioni improvvisate.
  • Facilitare analisi causali: passare dal “proviamo a riavviare” al “questo span rallenta dopo l’upgrade del driver DB”.
  • Allineare i segnali a SLO ed error budget (guidati da SLA): profondità, retention e cardinalità si dimensionano partendo dagli obiettivi di affidabilità esterni e interni.

Risultato: meno rumore, meno opinioni, più diagnosi rapide e decisioni informate.

Cos’è OpenTelemetry 🧪

OpenTelemetry (OTel) è uno standard aperto (CNCF) che fornisce specifiche, SDK e componenti per generare, raccogliere e trasportare segnali di observability (oggi: traces, metrics, logs; domani: profiles, e altro). Non è un database, non è una dashboard, non è “un altro agente magico”. È la lingua franca che evita lock‑in negli strumenti di backend.

La sua forza è l’architettura stratificata: le API definiscono interfacce neutrali così il codice applicativo non dipende da un vendor specifico. Gli SDK implementano buffering, sampling, export e performance per i singoli linguaggi (Go, Java, Python, JS, .NET, Rust…). L’instrumentation automatica ti permette di avere subito visibilità (HTTP, gRPC, DB, framework), mentre quella manuale aggiunge contesto di business dove conta davvero (ad esempio uno span “apply-discount-rule”). Il Collector funge da snodo: riceve (receivers), trasforma (processors) e inoltra (exporters) i dati verso più backend contemporaneamente, consentendoti di migrare o confrontare soluzioni senza rifattorizzare i servizi. Le semantic conventions danno coerenza: usare http.method ovunque evita il caos di varianti creative.

OTLP 📡

OTLP (OpenTelemetry Protocol) è il protocollo nativo usato da OpenTelemetry per trasportare signals di observability (traces, metrics, logs). È ottimizzato per efficienza e interoperabilità, supporta trasporto via gRPC (binario, streaming) e HTTP/JSON (più semplice da integrare). In pratica, le tue app e agent/SDK inviano dati in OTLP al Collector, che li elabora e li inoltra ai backend desiderati.

Punti chiave operativi:

  • Transport: otlp/grpc per prestazioni; otlp/http per ambienti con proxy/firewall restrittivi.
  • Sicurezza: TLS mTLS opzionale; attenzione a certificati e SNI quando passi attraverso LB.
  • Compat: receivers/exporters OTLP sono disponibili in quasi tutti i componenti dell’ecosistema.
  • Migrazioni: usare OTLP riduce lock‑in perché separa strumentazione dal backend.

I tre pilastri: metriche, log e tracing 🏛️

OpenTelemetry li chiama “signals”. Ognuno risponde a tipi di domande diversi.

Metriche 📊

Le metriche sono la vista macro del sistema: numeri compatti e rapidi da interrogare per capire se qualcosa sta divergen­do rispetto al comportamento normale. Non raccontano i dettagli fini (quelli sono dominio del tracing) ma eccellono nel mostrarti trend, saturazioni e stagionalità.

I tipi principali coprono pattern distinti: i Counter crescono soltanto (richieste totali, byte inviati) e facilitano rate & derivazioni; gli UpDownCounter misurano grandezze che entrano ed escono (connessioni attive, goroutine correnti); gli Histogram catturano distribuzioni (latenze, dimensioni payload) così da ragionare in percentili e non in medie bugiarde; le Gauge descrivono lo stato puntuale (spazio disco libero, queue length).

Per usarle bene: usa histogram invece della media quando misuri latenza o durata (la media nasconde le code lunghe); controlla la cardinalità delle label – ogni combinazione genera una serie, e aggiungere user_id è il modo più veloce per bruciare memoria e performance; versiona le metriche quando cambi semantica o naming, mantenendo un periodo di overlap per dashboard/alert legacy.

Log 🪵

I log sono la narrativa granulare: eventi discreti con contesto che spiegano i passaggi rilevanti. Non sostituiscono metriche o tracce: le completano. Se li usi per calcolare trend con grep ti stai creando un sistema di metriche inefficiente; se li usi per spiegare perché un ramo decisionale è stato preso, allora stai vincendo.

Rimando all’articolo dettagliato: Logging best practices.

In ottica OTel: Preferisci log strutturati (JSON con campi coerenti) così diventano query-abili; inserisci il trace_id e span_id quando sei nel contesto di una richiesta per saltare tra log e tracce; inviali al Collector che li ridistribuisce a sistemi specializzati (Loki per costi contenuti, Elasticsearch/OpenSearch per full-text avanzato, Splunk per analisi enterprise). Meno copy & paste di stacktrace inutili, più campi stabili e interrogabili.

Tracing 🔍

Il tracing risponde a: “cosa è successo esattamente durante questa richiesta?” e “dove stiamo spendendo tempo?”. Fondamentale nei sistemi distribuiti.

Concetti base:

  • Trace: rappresenta l’intero viaggio di una singola operazione end‑to‑end (es. richiesta utente → gateway → servizio A → DB → servizio B → cache…). È un DAG di span correlati da identificatori.
  • Span: unità atomica di lavoro (es. chiamata HTTP, query SQL, elaborazione batch). Ha: name, start_time, end_time, attributi chiave/valore, eventi (log leggeri), link e status.
  • SpanContext: contiene trace_id, span_id, flags, baggage.
  • Baggage: coppie chiave/valore propagate per arricchire contesto (attenzione a privacy e dimensioni).

Finalità del tracing:

Uso Obiettivo Esempio
Performance Identificare colli di bottiglia 80% tempo speso in payment-authorize
Distributed causality Seguire propagazione richiesta Correlare timeout frontend a latenza DB
Error analysis Localizzare failure point Span con status error + attributi stack
Capacity & tuning Stimare impatto scaling Confronto latenza pre/post ottimizzazione cache
SLO burn analysis Misurare contributo al budget errori Tracce lente > 2s in region eu-west-1

Tipologie pratiche:

  • Tracing distribuito: full path cross-service.
  • Local in-process spans: granularità interna (function boundaries, step di pipeline).
  • Synthetic / test traces: generate da job programmati per percorsi critici.
  • Cold start / init tracing: misurazione bootstrap di funzioni serverless.

Esempio semplificato (albero):

1
2
3
4
5
6
7
trace 4bf92f3577b34da6a3ce929d0e0e4736
└─ span GET /checkout (350ms)
   ├─ span call inventory (80ms)
   ├─ span call pricing (120ms)
   │   └─ span query SELECT price... (40ms)
   └─ span call payment (140ms)
       └─ span POST /psp/authorize (110ms)

Correlazione dei segnali 🧬

La magia non sta nell’avere tanti dati, ma nell’avere dati correlabili. Un alert di SLO burn rate ti porta alla metrica di latenza; da lì filtri il P99 e salti alle tracce lente; nella singola traccia individui lo span problematico e apri il log contestuale grazie al trace_id. Questo percorso riduce minuti (o ore) di ricerca a una sequenza naturale di click.

Esempi tipici

  • Log con trace_id → ricostruzione narrativa dell’esecuzione.
  • SLO rosso → drill-down su tracce anomale (percentili estremi) → root cause.
  • Cluster di tracce lente con attributo comune (db.system = postgres) → ottimizzazione mirata.
  • Annotation di deploy sulla timeline → correlazione immediata con spike errori.

Pipeline con OpenTelemetry Collector 🔄

Il Collector è il crocevia neutrale: centralizza ingest, trasformazione e inoltro dei signals. I receivers parlano con il mondo (OTLP, Prometheus scrape, Jaeger, Zipkin, StatsD); i processors applicano politiche (batch per efficienza, tail sampling per tenere solo le tracce interessanti, arricchimento attributi, redaction PII); gli exporters inviano a molteplici destinazioni (Jaeger, Tempo, Loki, Prometheus remote write, piattaforme SaaS). Le extensions aggiungono health check, pprof, zPages.

I benefici pratici: decoupling totale tra servizi e backend (cambiare destinazione è config, non codice), riduzione del vendor lock‑in (multi-export parallelo), sampling dinamico centralizzato invece che replicato, singoli punti di redaction/enrichment coerente. In breve: controllo fine senza toccare le applicazioni.

Strumenti diffusi per signal 📦

Metriche 📊

Per metriche time-series, Prometheus è lo standard de facto: semplice modello pull + label. Quando la scala cresce o la retention si allunga entrano in gioco VictoriaMetrics o Mimir per efficienza e compressione. Graphite sopravvive in ambienti legacy mentre InfluxDB resta forte in contesti IoT. Lato managed, Datadog e New Relic puntano su integrazioni out‑of‑the‑box; i cloud provider (CloudWatch, Google Cloud Monitoring, Azure Monitor) offrono integrazione nativa; Grafana Cloud fornisce stack Prometheus/Mimir gestito.

Log 🪵

Per log strutturati, Loki sfrutta indicizzazione per label (economico sui volumi alti). Elasticsearch/OpenSearch rimangono la scelta per ricerca full-text potente, al costo di gestione e tuning. Fluent Bit / Fluentd e Vector fungono da agenti/forwarder ad alte prestazioni. In SaaS, Splunk domina l’enterprise, Datadog Logs si integra col resto della piattaforma, Elastic Cloud semplifica il deployment di Elastic stack.

Tracing 🔍

Jaeger e Tempo sono le soluzioni open più diffuse: il primo maturo e collaudato, il secondo molto efficiente su storage oggetti. Zipkin ancora rilevante per semplicità. SigNoz e Elastic APM self-host offrono un approccio integrato. In SaaS: Honeycomb eccelle nelle query esplorative ad hoc, Lightstep (ServiceNow) nell’analisi causale complessa, Datadog/New Relic/Dynatrace nella copertura piattaforma, AWS X-Ray per integrazione rapida su stack Amazon.

All‑in / convergenti 🧩

Le piattaforme convergenti aggregano signals (metrics+logs+traces) e spesso aggiungono profiling: Datadog, New Relic, Dynatrace. Lo stack Grafana (Prometheus + Loki + Tempo + Mimir) è l’opzione modulare open. Elastic Observability unifica ingest e correlazione. Coralogix e Sumo Logic rappresentano alternative SaaS flessibili.

Finalità strategiche dell’observability 🧠

Dietro i grafici c’è un obiettivo strategico: comprimere il ciclo idea→apprendimento. Un’osservabilità matura accelera i feedback loop perché la risposta all’effetto di un cambiamento è immediata. Consente SLO basati su percezione reale dell’utente (latenza end‑to‑end, tassi di successo) e trasforma gli error budget in strumento di governance ingegneristica.

In ottica governance, la catena SLA → SLO → indicatori guida la profondità dell’osservabilità: tracce, log e metriche vanno raccolti al livello minimo che consente di rispettare gli SLO e gestire l’error budget. Ogni livello extra (sampling più denso, retention più lunga, label ad alta cardinalità) ha un costo misurabile: valuta sempre il rapporto beneficio/costo prima di abilitarlo.

Riduce direttamente il costo degli incidenti (meno ore uomo, meno interruzioni, meno contesto perso). Abilita architetture distribuite, asincrone, event-driven senza trasformare il debug in archeologia. Sblocca continuous verification: ogni canary o feature flag è monitorato con soglie e regressione controllata. Infine rafforza ownership e accountability: i team vedono l’impatto delle proprie decisioni in tempo reale.

Build vs buy: gestire osservabilità “in casa” 🏗️

Prima di scegliere stack o piattaforma, parti dagli SLO derivati dagli SLA: determinano quali segnali servono davvero, con quale granularità e per quanto tempo. La scelta tra self‑host, SaaS o ibrido va pesata contro il costo totale (ingest, storage, query, on‑call) e il beneficio rispetto agli obiettivi SLO.

Vantaggi self-host ✅

Offre controllo pieno: puoi definire retention multilivello (hot 7 giorni, warm 30, cold 180), regole di sampling adattive, confinamento dei dati in region per compliance. I costi diventano ottimizzabili: sposti vecchi log su storage economico, applichi compressione custom, downsampli metriche storiche.

Riduce il vendor lock‑in (cambiare backend è una modifica di configurazione nel Collector) e consente una personalizzazione profonda della pipeline (redaction, enrichment business-specific, tail-sampling condizionale su attributi). Inoltre facilita l’integrazione con ecosistemi interni (feature flag, eventi dominio, sistemi di billing).

Svantaggi self-host ❌

Il rovescio della medaglia è la complessità operativa: scaling di Prometheus (sharding, federation), cluster di Elastic/OpenSearch affamati di tuning, politiche di retention e backup da mantenere. Introduce un nuovo dominio “da gestire” con relativo on-call (se cade il sistema che osserva, si vola alla cieca).

Serve tuning costante (cardinalità metriche, query lente, storage che si riempie). Gli aggiornamenti major richiedono piani controllati. E soprattutto servono competenze dedicate: non basta saper installare un chart Helm, occorre capire modelli di dati, impatto delle label, gestione hot path.

Vantaggi SaaS ☁️

Il principale beneficio è la rapidità di adozione: strumentazione minima e sei operativo con dashboard e alert preconfigurati. Le piattaforme moderne portano in dote feature avanzate (anomaly detection, correlazioni automatiche tra signals, eBPF per tracing senza codice) che sarebbe costoso replicare.

La scalabilità elastica è trasparente e l’onere operativo è nullo. In contesti enterprise pesano anche SLA, certificazioni e audit trail già garantiti. All’inizio i costi sono prevedibili e giustificati dal time‑to‑value.

Svantaggi SaaS 🧾

La crescita di volumi (log verbosi, tracce ad alta cardinalità, retention estesa) può generare escalation di costi non lineare. L’adozione di feature proprietarie (query DSL, funzioni AI) aumenta il lock‑in psicologico e tecnico.

Le piattaforme spesso limitano personalizzazioni profonde: sampling avanzato condizionale, redaction complessa in pipeline, enrichment custom lato ingest. Rimane anche il tema della sovranità del dato: esportare log e trace fuori perimetro può essere critico in settori regolamentati se non si applica cifratura/pseudonimizzazione a monte.

Modello ibrido 🧪

Un approccio pragmatico: tenere in SaaS i signals ad alto valore analitico (metriche SLO, tracing campionato intelligente, error log) e gestire in self-host i volumi grezzi (log di debug, trace non critiche, metriche ad altissima cardinalità). Così ottieni insight rapidi dove serve e controllo dei costi sui bulk data. Il Collector abilita facilmente routing differenziato (multi-export) e politiche di filtraggio in ingresso.

Strategie di adozione incrementale 🚀

Prerequisito: chiarire SLA/SLO e tradurli in indicatori operativi (latency, availability, error rate) da cui derivano metriche/trace/log necessari.

Percorso suggerito:

  1. Correlazione rapida: aggiungi trace_id ai log senza cambiare ancora backend.
  2. Canary instrumentation: strumenta un servizio a basso rischio per validare overhead e flussi.
  3. Collector dual-export: invia a due backend per confronto e migrazione graduale.
  4. Sampling intelligente: combina head sampling percentuale con tail sampling su errori e lentezze.
  5. Standardizzazione: applica semantic conventions prima che ogni team inventi convenzioni locali.
  6. SLO operativi: collega il burn rate a decisioni (feature freeze, priorità hardening).

Errori comuni da evitare 🧨

Errori ricorrenti:

  • Osservabilità senza SLO: strumentare senza obiettivi legati a SLA/SLO porta costi alti e insight poco utili.
  • Tracing “a pioggia”: strumentare tutto al 100% senza filtrare genera rumore e costi.
  • Label ad alta cardinalità: inserire identificatori unici trasforma Prometheus in una fornace di RAM.
  • Duplicazione nei log: replicare attributi già presenti nello span appesantisce ingest e storage.
  • Retention infinita: i dati freddi raramente consultati drenano budget; definisci politiche a scadenza.
  • Collector cieco: se non monitori backlog, drop rate ed errori export, stai volando strumentato… ma alla cieca.

Checklist rapida ✅

  • Tutti i servizi espongono almeno un histogram di latenza principale.
  • Trace_id propagato da edge a DB.
  • Log strutturati con correlazione trace.
  • Sampling dinamico per errori e p99 lenti.
  • SLO definiti e monitorati (errore + latenza).
  • SLA mappati su SLO misurabili e indicatori tecnici.
  • Runbook incident aggiornati con dashboard/traces link.
  • Pipeline cost-aware (filtri, redaction, tiering storage).

Conclusione 🔮

OpenTelemetry non “risolve” l’observability: ti dà un vocabolario e una cassetta degli attrezzi. Il valore nasce da domande intelligenti, dati correlati e disciplina nel mantenere segnali utili (non solo tanti). Inizia semplice, misura, pota ciò che non serve, e lascia che i dati raccontino la storia del tuo sistema.

Se vuoi migliorare i tuoi log, prossimo passo: Logging best practices. Poi passa al tracing avanzato con sampling mirato.

Buona osservabilità (quella vera, non la buzzword). 😉

Ultimo aggiornamento il