Salta al contenuto principale

06 - Collector Pipeline - Receiving, Processing, and Exporting Telemetry

OTel Collector architecture, receivers, processors (batching, sampling, filtering), exporters, configuration, deployment patterns (agent, gateway, sidecar).

Cosa ne pensi di questo articolo?

06 - Collector Pipeline - Receiving, Processing, and Exporting Telemetry
ObservabilityFoto:Jayashankar MajhiPexels

In Breve

OTel Collector architecture, receivers, processors (batching, sampling, filtering), exporters, configuration, deployment patterns (agent, gateway, sidecar).

OTel Collector: Il Cuore del Pipeline di Telemetria

L'OpenTelemetry Collector e un componente standalone, vendor-agnostic, che riceve, processa e esporta dati di telemetria. Funziona come un proxy intelligente tra le applicazioni instrumentate e i backend di observability, offrendo un layer di astrazione che disaccoppia la generazione dei dati dalla loro destinazione finale.

Il Collector e il componente più critico di un'infrastruttura di observability in produzione. Senza di esso, ogni applicazione deve conoscere e gestire la connessione diretta al backend, rendendo difficile cambiare backend, aggiungere processing intermedio o gestire scenari di failover. Con il Collector, la configurazione dell'esportazione e centralizzata e le applicazioni devono solo sapere come raggiungere il Collector.

Cosa Imparerai in Questo Articolo

  • L'architettura interna del Collector: Receivers, Processors, Exporters
  • Come configurare il Collector con YAML
  • I Processors più importanti: batch, filter, attributes, tail_sampling
  • Pattern di deployment: Agent, Gateway e Sidecar
  • Scaling e alta disponibilità del Collector
  • Monitoraggio del Collector stesso (meta-observability)

Architettura del Collector

Il Collector ha un'architettura a pipeline composta da tre tipi di componenti, collegati tramite pipelines configurabili per ogni tipo di segnale (traces, metrics, logs):

Pipeline del Collector

Receivers (Ingresso) → Processors (Trasformazione) → Exporters (Uscita)

Un pipeline può avere più receivers (raccogliere da più fonti), una catena di processors (filtrare, arricchire, campionare) e più exporters (inviare a più backend contemporaneamente).

Receivers: Punti di Ingresso

I Receivers sono i punti di ingresso del Collector. Accettano dati di telemetria da varie fonti e li convertono nel formato interno OTel. Il receiver più comune e l'OTLP receiver, ma il Collector supporta decine di receivers per diversi protocolli e fonti.

Processors: Trasformazione dei Dati

I Processors modificano i dati tra il ricevimento e l'esportazione. Possono filtrare, arricchire, campionare, raggruppare e trasformare i segnali di telemetria. L'ordine dei processors nella pipeline e significativo: vengono eseguiti in sequenza.

Exporters: Destinazioni dei Dati

Gli Exporters inviano i dati processati alle destinazioni finali: backend di storage, servizi di visualizzazione o altri Collector. Un pipeline può avere più exporters per inviare gli stessi dati a destinazioni diverse contemporaneamente.

Configurazione Completa del Collector

Il Collector si configura con un file YAML che definisce receivers, processors, exporters e le pipelines che li collegano. Ecco una configurazione production-ready:


# otel-collector-config.yaml - Configurazione production-ready
receivers:
  # OTLP receiver: il protocollo nativo di OpenTelemetry
  otlp:
    protocols:
      grpc:
        endpoint: "0.0.0.0:4317"
        max_recv_msg_size_mib: 4
      http:
        endpoint: "0.0.0.0:4318"
        cors:
          allowed_origins: ["*"]

  # Prometheus receiver: scraping di metriche Prometheus
  prometheus:
    config:
      scrape_configs:
        - job_name: "kubernetes-pods"
          scrape_interval: 30s
          kubernetes_sd_configs:
            - role: pod
          relabel_configs:
            - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
              action: keep
              regex: true

  # Filelog receiver: raccolta log da file
  filelog:
    include: ["/var/log/pods/*/*/*.log"]
    operators:
      - type: json_parser
        timestamp:
          parse_from: attributes.time
          layout: "%Y-%m-%dT%H:%M:%S.%LZ"

processors:
  # Batch processor: raggruppamento per invii efficienti
  batch:
    send_batch_size: 1024
    send_batch_max_size: 2048
    timeout: 5s

  # Memory limiter: protezione da OOM
  memory_limiter:
    check_interval: 1s
    limit_mib: 512
    spike_limit_mib: 128

  # Resource processor: aggiungere attributi globali
  resource:
    attributes:
      - key: deployment.environment
        value: "production"
        action: upsert
      - key: collector.version
        value: "0.96.0"
        action: insert

  # Attributes processor: filtrare attributi sensibili
  attributes:
    actions:
      - key: http.request.header.authorization
        action: delete
      - key: db.query.text
        action: hash

  # Filter processor: scartare telemetria non necessaria
  filter:
    error_mode: ignore
    traces:
      span:
        - 'attributes["http.route"] == "/health"'
        - 'attributes["http.route"] == "/ready"'
    metrics:
      metric:
        - 'name == "http.server.request.duration" and resource.attributes["service.name"] == "debug-service"'

exporters:
  # OTLP exporter: verso Jaeger per le tracce
  otlp/jaeger:
    endpoint: "jaeger-collector:4317"
    tls:
      insecure: true

  # Prometheus exporter: esporre metriche per Prometheus
  prometheus:
    endpoint: "0.0.0.0:8889"
    resource_to_telemetry_conversion:
      enabled: true

  # Loki exporter: verso Loki per i log
  loki:
    endpoint: "http://loki:3100/loki/api/v1/push"
    default_labels_enabled:
      exporter: true
      job: true

  # Debug exporter: per testing
  debug:
    verbosity: basic
    sampling_initial: 5
    sampling_thereafter: 200

extensions:
  # Health check endpoint
  health_check:
    endpoint: "0.0.0.0:13133"

  # Performance profiling
  pprof:
    endpoint: "0.0.0.0:1777"

  # zPages: debugging UI built-in
  zpages:
    endpoint: "0.0.0.0:55679"

service:
  extensions: [health_check, pprof, zpages]

  pipelines:
    # Pipeline per le tracce
    traces:
      receivers: [otlp]
      processors: [memory_limiter, filter, attributes, batch]
      exporters: [otlp/jaeger, debug]

    # Pipeline per le metriche
    metrics:
      receivers: [otlp, prometheus]
      processors: [memory_limiter, resource, batch]
      exporters: [prometheus]

    # Pipeline per i log
    logs:
      receivers: [otlp, filelog]
      processors: [memory_limiter, resource, attributes, batch]
      exporters: [loki]

  telemetry:
    logs:
      level: info
    metrics:
      address: "0.0.0.0:8888"
      

Pattern di Deployment

Il Collector può essere deployato in tre pattern principali, ognuno con vantaggi e trade-off specifici. In ambienti di produzione, spesso si combinano più pattern.

1. Agent Mode (DaemonSet)

Un'istanza del Collector su ogni nodo del cluster (DaemonSet in Kubernetes). Ogni applicazione sul nodo invia telemetria al Collector locale via localhost, minimizzando la latenza di rete. L'agent esegue pre-processing leggero (batching, filtering) e inoltra al gateway.

2. Gateway Mode (Deployment)

Un pool centralizzato di Collector che riceve telemetria dagli agent o direttamente dalle applicazioni. Il gateway esegue processing pesante (tail sampling, aggregazione) e gestisce l'esportazione verso i backend. Scala orizzontalmente in base al volume di telemetria.

3. Sidecar Mode

Un'istanza del Collector per ogni pod, deployata come container sidecar. Offre isolamento completo tra applicazioni e permette configurazioni specifiche per servizio. E il pattern più costoso in termini di risorse ma il più flessibile.


# Kubernetes: Agent (DaemonSet) + Gateway (Deployment)

# Agent DaemonSet - uno per nodo
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: otel-collector-agent
  namespace: observability
spec:
  selector:
    matchLabels:
      app: otel-collector-agent
  template:
    metadata:
      labels:
        app: otel-collector-agent
    spec:
      containers:
        - name: collector
          image: otel/opentelemetry-collector-contrib:0.96.0
          args: ["--config=/etc/otel/config.yaml"]
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 512Mi
          ports:
            - containerPort: 4317  # OTLP gRPC
            - containerPort: 4318  # OTLP HTTP
          volumeMounts:
            - name: config
              mountPath: /etc/otel
      volumes:
        - name: config
          configMap:
            name: otel-agent-config
---
# Gateway Deployment - scalabile
apiVersion: apps/v1
kind: Deployment
metadata:
  name: otel-collector-gateway
  namespace: observability
spec:
  replicas: 3
  selector:
    matchLabels:
      app: otel-collector-gateway
  template:
    metadata:
      labels:
        app: otel-collector-gateway
    spec:
      containers:
        - name: collector
          image: otel/opentelemetry-collector-contrib:0.96.0
          args: ["--config=/etc/otel/config.yaml"]
          resources:
            requests:
              cpu: 500m
              memory: 1Gi
            limits:
              cpu: 2
              memory: 4Gi
      

Confronto Pattern di Deployment

Pattern Risorse Latenza Isolamento Uso Tipico
Agent Basse (per nodo) Minima (localhost) Per nodo Pre-processing, buffering
Gateway Medie-Alte (pool) Media (rete) Centralizzato Tail sampling, aggregazione
Sidecar Alte (per pod) Minima (localhost) Per servizio Config specifiche, isolamento

Meta-Observability: Monitorare il Collector

Il Collector e un componente critico dell'infrastruttura. Se smette di funzionare, si perde visibilità sull'intero sistema. Per questo e fondamentale monitorare il Collector stesso. OTel Collector espone metriche interne su un endpoint dedicato che può essere scrappato da Prometheus.

Metriche Chiave del Collector da Monitorare

  • otelcol_receiver_accepted_spans: span ricevuti con successo (throughput in ingresso)
  • otelcol_receiver_refused_spans: span rifiutati (potenziale sovraccarico)
  • otelcol_exporter_sent_spans: span esportati con successo (throughput in uscita)
  • otelcol_exporter_send_failed_spans: errori di esportazione (problemi con il backend)
  • otelcol_processor_batch_batch_send_size: dimensione dei batch inviati
  • otelcol_process_runtime_total_alloc_bytes: memoria allocata (rischio OOM)
  • otelcol_processor_dropped_spans: span scartati dai processor (data loss)

Conclusioni e Prossimi Passi

L'OTel Collector e il componente architetturale chiave per un'infrastruttura di observability scalabile e mantenibile. La sua architettura a pipeline (Receivers, Processors, Exporters) offre flessibilità totale nella gestione dei dati di telemetria, dal filtraggio dei dati sensibili al routing verso backend multipli.

La scelta del pattern di deployment (Agent, Gateway, Sidecar) dipende dalle esigenze specifiche dell'organizzazione. Il pattern più comune in produzione combina Agent (DaemonSet) per il pre-processing locale e Gateway (Deployment) per il processing centralizzato e l'esportazione.

Nel prossimo articolo esploreremo l'integrazione con i backend: come configurare Jaeger per le tracce, Prometheus per le metriche e Grafana per le dashboard di visualizzazione, creando uno stack di observability completo e funzionale.

Domande frequenti

Qual è il ruolo principale dell'OpenTelemetry Collector in un'infrastruttura di observability?

L'OpenTelemetry Collector riceve, processa e esporta dati di telemetria, funzionando come un proxy intelligente tra le applicazioni instrumentate e i backend di observability.

Come si configura il Collector per gestire i dati di telemetria?

Il Collector si configura con un file YAML che definisce receivers, processors, exporters e le pipeline che li collegano.

Quali sono i tre pattern principali di deployment del Collector?

I tre pattern principali di deployment del Collector sono Agent Mode (DaemonSet), Gateway Mode (Deployment) e Sidecar Mode. Ognuno ha vantaggi e trade-off specifici e possono essere combinati in ambienti di produzione.

Perché è importante monitorare il Collector stesso?

È importante monitorare il Collector perché se smette di funzionare, si perde visibilità sull'intero sistema. Il Collector espone metriche interne su un endpoint dedicato che può essere scrapato da Prometheus.

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