Backend Integration: Jaeger, Prometheus e Grafana
Dopo aver instrumentato le applicazioni e configurato il Collector, il passo successivo e collegare i dati di telemetria ai backend di storage e visualizzazione. Lo stack open source più diffuso combina Jaeger per le tracce distribuite, Prometheus per le metriche e Grafana come layer di visualizzazione unificato. Insieme, questi strumenti formano un sistema di observability completo e production-ready.
In questo articolo configureremo l'intero stack da zero, dal deployment con Docker Compose alla creazione di dashboard Grafana che correlano tracce, metriche e log in un'unica interfaccia.
Cosa Imparerai in Questo Articolo
- Setup completo di Jaeger per il tracing distribuito
- Configurazione di Prometheus per la raccolta metriche
- Dashboard Grafana per la visualizzazione unificata
- Loki per la raccolta e query dei log
- Correlazione tra tracce, metriche e log in Grafana
- Deployment dello stack completo con Docker Compose
Lo Stack Completo con Docker Compose
Il modo più rapido per avviare l'intero stack di observability e usare Docker Compose. La configurazione seguente deploya tutti i componenti necessari con le connessioni già configurate:
# docker-compose.observability.yaml
version: "3.9"
services:
# --- OpenTelemetry Collector ---
otel-collector:
image: otel/opentelemetry-collector-contrib:0.96.0
command: ["--config=/etc/otel/config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel/config.yaml
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
- "8889:8889" # Prometheus metrics export
- "13133:13133" # Health check
depends_on:
- jaeger
- loki
# --- Jaeger: Distributed Tracing Backend ---
jaeger:
image: jaegertracing/all-in-one:1.54
environment:
COLLECTOR_OTLP_ENABLED: "true"
SPAN_STORAGE_TYPE: "badger"
BADGER_EPHEMERAL: "false"
BADGER_DIRECTORY_VALUE: "/badger/data"
BADGER_DIRECTORY_KEY: "/badger/key"
volumes:
- jaeger_data:/badger
ports:
- "16686:16686" # Jaeger UI
- "14250:14250" # gRPC collector
# --- Prometheus: Metrics Backend ---
prometheus:
image: prom/prometheus:v2.50.0
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention.time=30d"
- "--web.enable-remote-write-receiver"
- "--enable-feature=exemplar-storage"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
# --- Loki: Log Aggregation ---
loki:
image: grafana/loki:2.9.4
command: -config.file=/etc/loki/local-config.yaml
volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml
- loki_data:/loki
ports:
- "3100:3100"
# --- Grafana: Visualization ---
grafana:
image: grafana/grafana:10.3.1
environment:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: observability
GF_FEATURE_TOGGLES_ENABLE: "traceqlEditor tempoSearch tempoBackendSearch"
volumes:
- ./grafana/provisioning:/etc/grafana/provisioning
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
depends_on:
- prometheus
- jaeger
- loki
volumes:
jaeger_data:
prometheus_data:
loki_data:
grafana_data:
Jaeger: Tracing Distribuito
Jaeger e il backend open source più usato per il tracing distribuito. Originariamente sviluppato da Uber e ora progetto della CNCF, Jaeger riceve le tracce dal Collector, le archivia e fornisce una UI per la ricerca, visualizzazione e analisi delle tracce distribuite.
L'integrazione con OpenTelemetry e nativa: Jaeger accetta dati OTLP direttamente, eliminando la necessità di conversioni. La UI di Jaeger offre la vista waterfall per le singole tracce, la comparazione tra tracce e la ricerca per servizio, operazione, durata e tag.
Funzionalità Principali di Jaeger
Trace Search: ricerca tracce per servizio, operazione, durata min/max, tag e time range.
Permette di trovare rapidamente le richieste problematiche.
Waterfall View: visualizzazione dettagliata di ogni span nella traccia, con
tempi, attributi, eventi e relazioni parent-child.
Trace Comparison: confronto side-by-side di due tracce per identificare differenze
nel comportamento tra una richiesta veloce e una lenta.
Service Dependencies: mappa automatica delle dipendenze tra servizi, derivata
dalle tracce raccolte.
Prometheus: Raccolta Metriche
Prometheus e il sistema di monitoring e alerting open source standard per le metriche. Usa un modello pull (scraping) per raccogliere metriche da endpoint HTTP, supporta un linguaggio di query potente (PromQL) e si integra nativamente con Grafana per la visualizzazione.
# prometheus.yml - Configurazione Prometheus
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "/etc/prometheus/rules/*.yml"
scrape_configs:
# Scraping del Collector OTel (metriche esportate)
- job_name: "otel-collector"
static_configs:
- targets: ["otel-collector:8889"]
scrape_interval: 10s
# Metriche interne del Collector
- job_name: "otel-collector-internal"
static_configs:
- targets: ["otel-collector:8888"]
# Scraping applicazioni con endpoint /metrics
- job_name: "applications"
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: (.+)
replacement: "${1}:${2}"
# Scraping Jaeger
- job_name: "jaeger"
static_configs:
- targets: ["jaeger:14269"]
# Scraping Prometheus stesso
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
Grafana: Visualizzazione Unificata
Grafana e il layer di visualizzazione che unifica tracce, metriche e log in un'unica interfaccia. Supporta nativamente Jaeger, Prometheus e Loki come data source, permettendo di creare dashboard che correlano tutti i segnali di telemetria.
# grafana/provisioning/datasources/datasources.yml
apiVersion: 1
datasources:
# Prometheus per le metriche
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
jsonData:
exemplarTraceIdDestinations:
- name: traceID
datasourceUid: jaeger
httpMethod: POST
# Jaeger per le tracce
- name: Jaeger
type: jaeger
access: proxy
url: http://jaeger:16686
uid: jaeger
jsonData:
tracesToLogsV2:
datasourceUid: loki
filterByTraceID: true
filterBySpanID: true
tracesToMetrics:
datasourceUid: Prometheus
# Loki per i log
- name: Loki
type: loki
access: proxy
url: http://loki:3100
uid: loki
jsonData:
derivedFields:
- datasourceUid: jaeger
matcherRegex: "trace_id=(\\w+)"
name: TraceID
url: "${__value.raw}"
Correlazione tra Segnali in Grafana
Il vero potere di Grafana emerge quando i tre data source sono configurati per la correlazione. Questo significa poter navigare da una metrica a una traccia, da una traccia ai log, e viceversa, in un flusso di debug continuo.
Flusso di Correlazione in Grafana
Dashboard metriche: vedi un picco nella latenza P99 →
clic su "Exemplar" nel grafico → apertura della traccia in Jaeger →
identifichi lo span lento (payment-gateway) → clic su "View Logs" →
apertura log filtrati in Loki con il trace_id → trovi il messaggio
di errore "connection timeout to payment provider".
Questo flusso trasforma il debugging da ore a minuti.
Loki: Aggregazione dei Log
Loki e il sistema di aggregazione log di Grafana, progettato per essere cost-effective e semplice da operare. A differenza di Elasticsearch, Loki indicizza solo le label (metadata), non il contenuto completo dei log, riducendo drasticamente i costi di storage e la complessità operativa.
# loki-config.yaml
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 168h
max_query_series: 500
max_query_parallelism: 2
analytics:
reporting_enabled: false
Query Essenziali per ogni Backend
- Jaeger: ricerca per service, operation, min/max duration, tags (es.
error=true) - Prometheus (PromQL):
rate(http_requests_total[5m]),histogram_quantile(0.99, ...) - Loki (LogQL):
{service="order-service"} |= "error" | json | trace_id != "" - Grafana Explore: split view per confrontare metriche e tracce side-by-side
Conclusioni e Prossimi Passi
Lo stack Jaeger + Prometheus + Loki + Grafana fornisce un sistema di observability completo, open source e production-ready. La chiave del successo e la correlazione: configurare i data source in Grafana per navigare fluidamente tra metriche, tracce e log, trasformando il debugging da un processo manuale e lungo a un flusso guidato e rapido.
Docker Compose e ideale per sviluppo e testing, mentre in produzione lo stack viene deployato su Kubernetes con Helm charts dedicati (jaeger-operator, kube-prometheus-stack, loki-stack).
Nel prossimo articolo approfondiremo la context propagation, analizzando come correlare log e tracce tramite trace ID, il protocollo W3C Baggage per il trasporto di metadata tra servizi, e i pattern per una correlazione efficace tra tutti i segnali.
Domande frequenti
Come funziona la combinazione di Jaeger, Prometheus e Grafana per creare un sistema di observability completo?
Questi strumenti formano un sistema di observability completo e production-ready, in cui Jaeger gestisce le tracce distribuite, Prometheus raccoglie le metriche e Grafana fornisce la visualizzazione unificata.
Qual è il vantaggio dell'integrazione nativa di OpenTelemetry con Jaeger?
L'integrazione nativa di OpenTelemetry con Jaeger elimina la necessità di conversioni dei dati, rendendo più facile e veloce l'invio delle tracce a Jaeger.
Come funziona la correlazione tra segnali in Grafana?
La correlazione tra segnali in Grafana permette di navigare fluidamente tra metriche, tracce e log, trasformando il debugging da un processo manuale e lungo a un flusso guidato e rapido.
Qual è la differenza principale tra Loki e Elasticsearch per quanto riguarda l'aggregazione dei log?
Loki indicizza solo le label (metadata) dei log, non il contenuto completo, riducendo drasticamente i costi di storage e la complessità operativa.

Commenti
Caricamento commenti...
Accedi per commentare