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.







