Salta al contenuto principale

10 - Sampling Strategies - Reducing Telemetry Volume and Costs

Head-based sampling, tail-based sampling, probabilistic sampling, adaptive sampling, cost optimization, accuracy trade-offs.

Cosa ne pensi di questo articolo?

10 - Sampling Strategies - Reducing Telemetry Volume and Costs
ObservabilityFoto:Lukas BlazekPexels

In Breve

Head-based sampling, tail-based sampling, probabilistic sampling, adaptive sampling, cost optimization, accuracy trade-offs.

Sampling Strategies: Ridurre Volume e Costi della Telemetria

In un sistema distribuito con centinaia di microservizi e migliaia di richieste al secondo, raccogliere ogni traccia e proibitivamente costoso. Il sampling (campionamento) e la tecnica che permette di selezionare un sottoinsieme rappresentativo delle tracce, riducendo il volume di dati e i costi di storage senza perdere la capacità di diagnosticare i problemi.

La sfida del sampling e trovare il giusto equilibrio: campionare troppo poco riduce la visibilità; campionare troppo aumenta i costi. Le strategie di sampling avanzate permettono di mantenere tutte le tracce con errori e le richieste lente, scartando solo il traffico "normale" e ripetitivo.

Cosa Imparerai in Questo Articolo

  • Head-based sampling: decisione all'inizio della traccia
  • Tail-based sampling: decisione alla fine della traccia
  • Probabilistic sampling e rate limiting
  • Configurazione del sampling nel Collector
  • Strategie di ottimizzazione dei costi
  • Trade-off tra accuratezza e costi

Head-Based Sampling

Il head-based sampling prende la decisione di campionare una traccia all'inizio, nel primo span (root span). La decisione viene poi propagata a tutti i servizi downstream attraverso il flag sampled nel traceparent header. Se il root span decide di non campionare, nessun servizio nella catena registrera span per quella traccia.

Il vantaggio principale e la semplicità e l'efficienza: la decisione viene presa immediatamente, senza dover attendere il completamento della traccia. Lo svantaggio e che non conosce il risultato della richiesta al momento della decisione: una traccia con errore potrebbe essere scartata.


from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.sampling import (
    TraceIdRatioBased,
    ParentBasedTraceIdRatio,
    ALWAYS_ON,
    ALWAYS_OFF,
)

# --- 1. Probability Sampler (25% delle tracce) ---
# Ogni traccia ha il 25% di probabilità di essere campionata
sampler_25 = TraceIdRatioBased(0.25)

# --- 2. ParentBased Sampler (rispetta la decisione del parent) ---
# Se il parent e campionato, il figlio e campionato
# Se non c'è parent, usa il ratio specificato
sampler_parent = ParentBasedTraceIdRatio(0.25)

# --- 3. Configurazione nel TracerProvider ---
provider = TracerProvider(
    sampler=ParentBasedTraceIdRatio(0.25)
)
trace.set_tracer_provider(provider)

# --- 4. Configurazione via variabili d'ambiente ---
# OTEL_TRACES_SAMPLER=parentbased_traceidratio
# OTEL_TRACES_SAMPLER_ARG=0.25
      

Tipi di Head-Based Sampler

Sampler Comportamento Uso Tipico
AlwaysOn Campiona tutte le tracce (100%) Sviluppo, testing, servizi a basso traffico
AlwaysOff Non campiona mai (0%) Disabilitare il tracing temporaneamente
TraceIdRatioBased Campiona una percentuale fissa Approccio semplice per ridurre il volume
ParentBased Rispetta la decisione del parent Garantire consistenza across servizi

Tail-Based Sampling

Il tail-based sampling prende la decisione di campionare una traccia dopo che tutti gli span sono stati raccolti, analizzando la traccia completa. Questo permette decisioni intelligenti basate sul risultato della richiesta: mantenere tutte le tracce con errori, le richieste lente e le tracce anomale, scartando solo il traffico ripetitivo e di successo.

Il tail-based sampling richiede un componente centralizzato (tipicamente il Collector in modalità Gateway) che raccoglie tutti gli span di una traccia, li assembla, valuta le policy di campionamento e decide se conservare o scartare l'intera traccia.


# Configurazione tail_sampling nel Collector Gateway
processors:
  tail_sampling:
    # Tempo massimo per attendere tutti gli span di una traccia
    decision_wait: 30s
    # Numero massimo di tracce in attesa di decisione
    num_traces: 100000
    # Numero atteso di nuove tracce al secondo
    expected_new_traces_per_sec: 1000

    policies:
      # Policy 1: mantenere TUTTE le tracce con errori
      - name: errors-policy
        type: status_code
        status_code:
          status_codes:
            - ERROR

      # Policy 2: mantenere le tracce lente (latenza > 2s)
      - name: latency-policy
        type: latency
        latency:
          threshold_ms: 2000

      # Policy 3: mantenere tracce con attributi specifici
      - name: vip-customers
        type: string_attribute
        string_attribute:
          key: customer.tier
          values:
            - premium
            - enterprise

      # Policy 4: campionamento probabilistico per il resto
      - name: probabilistic-policy
        type: probabilistic
        probabilistic:
          sampling_percentage: 10

      # Policy 5: rate limiting globale
      - name: rate-limiting
        type: rate_limiting
        rate_limiting:
          spans_per_second: 500

      # Policy 6: policy composita (AND/OR)
      - name: composite-policy
        type: composite
        composite:
          max_total_spans_per_second: 1000
          policy_order: [errors-policy, latency-policy, probabilistic-policy]
          rate_allocation:
            - policy: errors-policy
              percent: 50
            - policy: latency-policy
              percent: 30
            - policy: probabilistic-policy
              percent: 20
      

Confronto Head vs Tail Sampling

Head-Based vs Tail-Based Sampling

Aspetto Head-Based Tail-Based
Momento della decisione Inizio della traccia Fine della traccia
Conoscenza del risultato No Si (errori, latenza, attributi)
Risorse richieste Minime (distribuite) Significative (centralizzate)
Consistenza Sempre consistente Rischio di span orfani
Complessità Bassa Alta (infrastruttura dedicata)
Errori catturati Solo se campionati casualmente Tutti (policy dedicata)

Strategie di Ottimizzazione dei Costi

I costi di observability crescono con il volume di telemetria. Le strategie di ottimizzazione si concentrano su tre leve: ridurre il volume di tracce, ridurre il numero di attributi per span e ottimizzare la retention nel backend.


# Strategia di ottimizzazione multi-livello

# 1. Filtrare il rumore nel Collector
processors:
  filter:
    traces:
      span:
        # Eliminare health check e readiness probe
        - 'attributes["http.route"] == "/health"'
        - 'attributes["http.route"] == "/ready"'
        - 'attributes["http.route"] == "/metrics"'
        # Eliminare richieste di asset statici
        - 'attributes["http.route"] =~ "/static/.*"'

  # 2. Rimuovere attributi ad alta cardinalita
  attributes:
    actions:
      # Rimuovere header sensibili
      - key: http.request.header.authorization
        action: delete
      - key: http.request.header.cookie
        action: delete
      # Troncare query SQL lunghe
      - key: db.query.text
        action: hash

  # 3. Tail sampling intelligente
  tail_sampling:
    policies:
      - name: keep-errors
        type: status_code
        status_code:
          status_codes: [ERROR]
      - name: keep-slow
        type: latency
        latency:
          threshold_ms: 1000
      - name: sample-rest
        type: probabilistic
        probabilistic:
          sampling_percentage: 5

  # 4. Batch per efficienza
  batch:
    send_batch_size: 2048
    timeout: 10s
      

Checklist per l'Ottimizzazione dei Costi

  • Filtrare il rumore: eliminare health check, readiness probe e asset statici prima del backend
  • Controllare la cardinalita: limitare le label delle metriche a valori bounded (max 5-7 label per metrica)
  • Tail sampling sugli errori: mantenere il 100% delle tracce con errori, campionare il resto
  • Retention differenziata: retention lunga per metriche aggregate (90 giorni), breve per tracce raw (7-14 giorni)
  • Compressione: abilitare gzip/zstd nel Collector per ridurre il traffico di rete
  • Downsampling metriche: ridurre la risoluzione delle metriche storiche (da 15s a 5m dopo 7 giorni)

Adaptive Sampling

L'adaptive sampling adatta automaticamente il tasso di campionamento in base al volume di traffico corrente. Quando il traffico e basso, campiona una percentuale maggiore; quando il traffico e alto, riduce il tasso per mantenere il volume entro i limiti di budget.

Il rate limiting nel tail sampling del Collector e una forma semplice di adaptive sampling: spans_per_second: 500 garantisce un volume massimo costante indipendentemente dal traffico. Per strategie più sofisticate, servono soluzioni custom o servizi SaaS che implementano l'adaptive sampling a livello di piattaforma.

Conclusioni e Prossimi Passi

Il sampling e una competenza fondamentale per gestire l'observability a scala. La scelta della strategia dipende dal volume di traffico, dal budget e dal livello di visibilità richiesto. L'approccio consigliato e combinare head-based sampling per la riduzione base del volume con tail-based sampling per garantire che errori e anomalie vengano sempre catturati.

La regola d'oro e: campionare le tracce, mai le metriche. Le metriche aggregate hanno un costo fisso indipendente dal traffico e forniscono la visibilità di alto livello necessaria per gli alert. Le tracce sono costose ma necessarie solo per il debugging dettagliato.

Nel prossimo articolo esploreremo l'AI observability, analizzando come tracciare le chiamate ai Large Language Model, monitorare l'utilizzo dei token, le latenze delle inferenze e il comportamento degli agenti AI.

Domande frequenti

Qual è la principale sfida del sampling in un sistema distribuito?

La principale sfida del sampling è trovare il giusto equilibrio tra campionare troppo poco, che riduce la visibilità, e campionare troppo, che aumenta i costi.

Qual è il vantaggio principale del head-based sampling?

Il vantaggio principale del head-based sampling è la sua semplicità e efficienza, poiché la decisione di campionare viene presa immediatamente senza dover attendere il completamento della traccia.

Qual è il vantaggio del tail-based sampling?

Il vantaggio del tail-based sampling è che permette decisioni intelligenti basate sul risultato della richiesta, mantenendo tutte le tracce con errori, le richieste lente e le tracce anomale.

Qual è la regola d'oro per il sampling?

La regola d'oro è campionare le tracce, mai le metriche, poiché le metriche aggregate hanno un costo fisso indipendente dal traffico e forniscono la visibilità di alto livello necessaria per gli alert.

Fonti e approfondimenti

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti