
Monitoring e alerting per data pipeline
Come monitorare la salute delle pipeline dati e ricevere alert quando qualcosa si rompe.
Cosa imparerai
- Impostare controlli di freschezza, volume e schema con owner, severità e azione per ogni alert
- Rilevare anomalie con z-score su finestra mobile e scala di escalation legata alla severità
Collegamenti
Monitoring e alerting per data pipeline
Questa lezione appartiene al binario ml-tabellare e parla di un’attività che non fa notizia finché non viene trascurata: sapere, in tempo, che una pipeline si è rotta e chi deve occuparsene.
Che cosa fa davvero il monitoring
Il monitoring trasforma guasti di pipeline in alert con owner, severità e azione attesa. In sostanza: il problema non deve gridare nel vuoto, deve trovare una persona pronta a rispondere.
La sequenza per impostare i controlli
- Definisci freschezza, volume e schema attesi per ogni tabella critica.
- Assegna owner, severità e tempo di risposta a ogni alert.
- Collega ogni alert a diagnosi iniziale e azione operativa scritta.
- Rivedi ogni settimana gli alert ignorati per tagliare il rumore.
Tre livelli di controllo, tutti necessari
I controlli sono tre e servono tutti. Il primo verifica se il flusso è girato, con tempi ed errori da orchestratore. Il secondo verifica se i dati sono corretti, con test su valori nulli, unicità, valori ammessi e volumi giornalieri contro media mobile. Il terzo verifica se i numeri hanno senso, con soglie statistiche su metriche core e confronto con periodo precedente e stagionalità nota.
Verdetto: flusso girato, dati corretti e numeri plausibili; se manca un livello, il guasto passa in silenzio.
Che cosa rende utile un alert
Un alert utile dichiara tre voci: proprietario, azione richiesta, urgenza. Senza queste voci diventa rumore che il team impara a ignorare.
# Example: dbt Elementary alert config
alerts:
- test: unique_order_id
severity: critical
owner: "@data-platform"
action: "Blocca deploy produzione finché risolto"
- test: row_count_anomaly
severity: warning
owner: "@data-analytics"
action: "Verifica entro 2 ore, investiga se trend persiste"
La scala di escalation
| Severità | Significato | Tempo di risposta | Canale |
|---|---|---|---|
| Critical | Dati errati visibili a clienti o board | 15 minuti | PagerDuty, chiamata |
| High | Pipeline bloccata, dashboard non aggiornate | 1 ora | Slack @channel |
| Medium | Anomalia statistica, possibile degrado | Entro il giorno | Slack channel |
| Low | Warning, fluttuazione stagionale possibile | Prossimo standup | Dashboard alert log |
La severità decide canale e tempo, non l’umore del turno. Un job con stato verde ma tabella ferma da due giorni resta un incidente di freschezza, non un successo.
Verdetto: severità scritta prima dell’incidente e canale legato alla severità.
Esempio SQL: costruire una vista di controllo
Il pattern crea una base analitica con metrica, segmento e finestra temporale. Così confronti periodi e gruppi senza riscrivere la logica.
WITH base_events AS (
SELECT
user_id,
account_id,
event_type,
event_time,
DATE_TRUNC('week', event_time) AS week,
source,
device_type
FROM events
WHERE event_time >= CURRENT_DATE - INTERVAL '180 days'
AND user_id IS NOT NULL
),
weekly_user_metrics AS (
SELECT
week,
user_id,
COALESCE(source, 'unknown') AS source,
COALESCE(device_type, 'unknown') AS device_type,
COUNT(*) AS total_events,
COUNT(DISTINCT DATE(event_time)) AS active_days,
COUNT(DISTINCT event_type) AS event_diversity,
MAX(CASE WHEN event_type IN ('purchase', 'subscribe', 'activation') THEN 1 ELSE 0 END) AS reached_key_outcome
FROM base_events
GROUP BY week, user_id, source, device_type
)
SELECT
week,
source,
device_type,
COUNT(DISTINCT user_id) AS users,
ROUND(AVG(active_days), 2) AS avg_active_days,
ROUND(AVG(event_diversity), 2) AS avg_event_diversity,
ROUND(AVG(reached_key_outcome) * 100, 2) AS key_outcome_rate
FROM weekly_user_metrics
GROUP BY week, source, device_type
ORDER BY week, source, device_type;
Esempio Python: controllare stabilità e anomalie
Il controllo su finestra mobile alimenta alert di anomalia senza reagire a ogni oscillazione.
# df contiene: week, segment, users, key_outcome_rate
# key_outcome_rate espresso in percentuale, es. 12.4
df = df.sort_values(['segment', 'week']).copy()
df['previous_rate'] = df.groupby('segment')['key_outcome_rate'].shift(1)
df['wow_change_pp'] = df['key_outcome_rate'] - df['previous_rate']
df['rolling_mean'] = df.groupby('segment')['key_outcome_rate'].transform(
lambda s: s.rolling(4, min_periods=2).mean()
)
df['rolling_std'] = df.groupby('segment')['key_outcome_rate'].transform(
lambda s: s.rolling(4, min_periods=2).std()
)
df['z_score'] = (df['key_outcome_rate'] - df['rolling_mean']) / df['rolling_std']
anomalies = df[df['z_score'].abs() >= 2].sort_values('z_score')
print(anomalies[['week', 'segment', 'key_outcome_rate', 'wow_change_pp', 'z_score']])
La regione in cui il verde non bastava
Il 28 febbraio 2017 un comando errato durante un intervento di debug manda fuori uso lo storage S3 nella regione us-east-1 di AWS per circa 4 ore. Pagine, pipeline e dashboard che dipendono da quella regione restano degradate senza un segnale chiaro su chi deve intervenire. L’incidente mostra il valore di controlli di freschezza e volume con owner scritto: se la tabella non si aggiorna, l’alert deve partire dal dato mancante, non dallo stato verde dell’orchestratore.
Domande finali
- Quale controllo di freschezza segnala una tabella ferma da due giorni?
- Quale owner e quale severità assegni a ogni alert critico?
- Quale diagnosi iniziale accompagna un’anomalia di volume?
- Quale soglia statistica evita di inseguire il rumore settimanale?
Bloccato su questo argomento o vuoi applicarlo al tuo caso? Prenota una call di 15 minuti con un analista esperto.
Percorso collegato
Lezioni da leggere insieme
Questi collegamenti portano la lezione dentro il resto del corso: basi da riprendere, passaggi successivi e connessioni tematiche tra moduli.