👁️ O que Monitorar
Monitorar tudo é ruído; não monitorar nada é cegueira. As 4 métricas essenciais abaixo cobrem 95% das falhas reais de pipelines em produção — e formam o dashboard mínimo viável.
Volume
Métrica 1Registros hoje vs média histórica das últimas 4 semanas. Detecta falha de ingestão (queda) ou duplicação (pico).
Frescor
Métrica 2Horas desde a última atualização confirmada via generated_at. Detecta pipeline parado ou falha de agendamento.
Nulos
Métrica 3Percentual de nulos em colunas críticas vs baseline. Detecta mudança de campo obrigatório para opcional na fonte.
Schema
Métrica 4Drift detectado: nova coluna, coluna removida, tipo alterado. Detecta mudança silenciosa na API ou no sistema fonte.
SQL para as 4 métricas em uma única query
-- Dashboard query — executa em < 100ms
SELECT
(SELECT COUNT(*) FROM revenue_by_client_month
WHERE DATE_TRUNC('day', month) = CURRENT_DATE - 1) AS volume_hoje,
(SELECT ROUND(EXTRACT(EPOCH FROM NOW() - MAX(generated_at))/3600, 1)
FROM revenue_by_client_month) AS horas_desde_update,
(SELECT ROUND(AVG(CASE WHEN total_revenue_usd IS NULL THEN 1.0 ELSE 0.0 END)*100, 2)
FROM revenue_by_client_month) AS null_pct_revenue,
-- schema: checar externamente via hash de DESCRIBE TABLE
(SELECT COUNT(*) FROM pipeline_runs
WHERE status = 'FAIL' AND generated_at > NOW() - INTERVAL 24 HOURS) AS falhas_24h
🖥️ Construindo o Painel sobre DuckDB
Ferramentas complexas são overkill para projetos de dados de médio porte. Um painel em Python + Streamlit resolve 90% dos casos em 30 minutos.
dashboard.py — Painel Mínimo com Streamlit
import streamlit as st
import duckdb
from datetime import datetime, timezone
st.set_page_config(page_title="Pipeline Monitor", layout="wide")
st.title("🔔 Pipeline Monitor — BrightPath")
conn = duckdb.connect('engagement.duckdb')
# Buscar métricas
metrics = conn.execute("""
SELECT
COUNT(*) AS total_rows,
ROUND(EXTRACT(EPOCH FROM NOW() - MAX(generated_at))/3600, 1) AS hours_since_update,
ROUND(AVG(CASE WHEN total_revenue_usd IS NULL THEN 1.0 ELSE 0.0 END)*100, 2) AS null_pct
FROM revenue_by_client_month
""").fetchone()
# Cards de status com semáforo
col1, col2, col3, col4 = st.columns(4)
with col1:
delta = "🟢 OK" if metrics[0] > 1000 else "🔴 BAIXO"
st.metric("Volume", f"{metrics[0]:,}", delta)
with col2:
freshness_ok = metrics[1] < 26
delta = "🟢 OK" if freshness_ok else "🔴 STALE"
st.metric("Frescor", f"{metrics[1]}h", delta)
with col3:
null_ok = metrics[2] < 2
delta = "🟢 OK" if null_ok else "🔴 ALTO"
st.metric("Nulos Revenue", f"{metrics[2]}%", delta)
with col4:
# Schema: comparar hash atual com esperado
st.metric("Schema", "OK", "🟢 Sem drift")
# Tabela de alertas ativos
st.subheader("Alertas Ativos")
alerts = conn.execute("""
SELECT table_name, generated_at, status, notes
FROM pipeline_runs
WHERE status = 'FAIL'
AND generated_at > NOW() - INTERVAL 24 HOURS
ORDER BY generated_at DESC
""").fetchdf()
st.dataframe(alerts, use_container_width=True)
💡 Como Rodar
pip install streamlit duckdb
streamlit run dashboard.py
O painel abre no browser em localhost:8501 e atualiza automaticamente. Para atualização periódica automática, use st.rerun() com time.sleep(300).
🔔 Alertas por Anomalia — Threshold e Lógica de Disparo
Alertas sem threshold definido geram ruído. A lógica correta é: condição específica + threshold numérico + cooldown + canal + responsável.
Tipos de Threshold
Threshold Estático
Valor fixo definido no SLA: null_rate > 5%, horas_desde_update > 26, volume < 500.
Melhor para: métricas com expectativa clara e estável. Simples de implementar e de explicar para não-técnicos.
Threshold Dinâmico (Z-Score)
Alertar quando o valor atual está a mais de 3 desvios padrão da média histórica: (valor - média) / σ > 3.
Melhor para: métricas com sazonalidade forte onde um threshold fixo geraria muitos falsos positivos.
Sistema de Alertas com Cooldown
import json
from pathlib import Path
from datetime import datetime, timedelta
COOLDOWN_HOURS = 1
ALERT_STATE_FILE = '.alert_state.json'
def deve_alertar(alert_id: str, cooldown_h: int = COOLDOWN_HOURS) -> bool:
state = {}
if Path(ALERT_STATE_FILE).exists():
with open(ALERT_STATE_FILE) as f:
state = json.load(f)
last_alert = state.get(alert_id)
if last_alert:
last_dt = datetime.fromisoformat(last_alert)
if datetime.now() - last_dt < timedelta(hours=cooldown_h):
return False # ainda em cooldown
# Registrar este alerta
state[alert_id] = datetime.now().isoformat()
with open(ALERT_STATE_FILE, 'w') as f:
json.dump(state, f)
return True
# Uso
if null_rate > 0.05 and deve_alertar('null_rate_revenue'):
notificar_slack(
f"⚠️ WARNING: null_rate em revenue = {null_rate:.1%} (threshold: 5%)",
severity='WARNING'
)
🤖 Integrando Alertas com Agentes
Alertas sem diagnóstico geram trabalho de investigação. Um agente com acesso ao DuckDB consegue entregar o diagnóstico automaticamente — reduzindo o tempo de resposta de horas para minutos.
Alerta dispara o agente com contexto
Quando null_rate ultrapassa threshold, o sistema cria um prompt para o agente com o contexto completo: qual métrica, qual valor, qual threshold, e quais queries executar para investigar.
Agente investiga com múltiplas queries
O agente executa queries de diagnóstico: qual período está afetado? Quais clientes têm mais nulos? Quando começou o problema? A sequência de queries é definida pelo agente com base no contexto.
Notificação com diagnóstico completo
🔴 CRITICAL — Pipeline BrightPath
Métrica: null_rate em revenue
Valor atual: 8.3% | Threshold: 5%
Período afetado: 2026-05-12 a 2026-05-14
Causa provável: Stripe API retornou amount=null para 847 transações de plano Free
Ação recomendada: Verificar mudança na API do Stripe para plano Free
Status agente: Respostas sobre receita bloqueadas
📊 Dashboard MVP vs Dashboard Completo
O MVP cobre 90% das necessidades reais. O dashboard completo é útil para times grandes e pipelines críticos — mas é over-engineering para projetos menores. Saber onde parar economiza semanas.
✓ Dashboard MVP — 30 minutos para construir
- ✓4 cards de status com semáforo (verde/amarelo/vermelho)
- ✓Tabela de alertas ativos com timestamp e severidade
- ✓Botão manual de reprocessamento com confirmação
- ✓Histórico de 7 dias das últimas execuções
- ✓Link para runbook de emergência
Dashboard Completo — semanas para construir
- →Histórico de 90 dias com gráficos de tendência
- →Análise de causa raiz assistida por IA
- →Integração com sistema de tickets (Jira, Linear)
- →Comparação de versões de dados lado a lado
- →Relatório de SLA automático para stakeholders
💡 Quando evoluir do MVP para o completo
Evolua quando: (1) o time tem mais de 3 engenheiros trabalhando no pipeline, (2) o SLA do cliente exige relatório formal de uptime, (3) você tem mais de 10 fontes de dados para monitorar. Para projetos com 1-3 engenheiros e menos de 10 fontes, o MVP é suficiente por mais de 12 meses.
💡 Casos onde o Painel Salvou um Projeto
Esses casos mostram o ROI concreto do monitoramento. São os argumentos que convencem clientes e gestores a investir em qualidade de dados.
Caso 1 — O Fuso Horário Errado
O painel alertou queda de 40% no volume de transações às 18h de uma quinta-feira. O engenheiro investigou e descobriu que o servidor de ingestão havia sido migrado para um fuso horário diferente — os dados de "sexta" estavam sendo rotulados como "quinta" e os dados do final do dia estavam entrando com data do dia seguinte. Sem o alerta de volume, isso seria descoberto somente quando o relatório semanal fosse entregue ao cliente com números errados.
Tempo de detecção com painel: 3 horas. Tempo estimado sem painel: 5 dias.
Caso 2 — Schema Drift da API do Stripe
Na sexta à tarde, o monitor de schema detectou drift: a coluna "metadata" do Stripe havia mudado de VARCHAR para JSON nativo. O pipeline foi atualizado e testado no fim de semana. Na segunda-feira, quando a maioria dos projetos sem monitoramento teria o pipeline quebrado, o sistema já estava rodando com o novo schema. O cliente nunca soube que algo havia mudado.
Schema drift sem monitoramento: pipeline quebra na segunda. Com monitoramento: resolvido no fim de semana.
Caso 3 — Relatório com Dados Incorretos Evitado
O range check detectou valores de receita negativa em 12 registros — um bug de migração que havia sobrescrito valores positivos com negativos durante um reprocessamento parcial. A receita total do mês estava $47.000 mais baixa que o real. O erro foi detectado e corrigido antes que o agente respondesse qualquer pergunta sobre receita do período afetado.
Sem range check: o cliente receberia uma resposta com a receita $47k menor que o real. Com range check: corrigido silenciosamente.
✓ Alertas que funcionam
- ✓Threshold numérico específico e documentado
- ✓Diagnóstico automático junto com o alerta
- ✓Cooldown para evitar spam
- ✓Ação recomendada incluída na notificação
- ✓Responsável identificado por tipo de alerta
✗ Alertas que ninguém lê
- ✗"Algo pode ter dado errado" sem especificar o quê
- ✗100 alertas por dia — todos ignorados
- ✗Sem diagnóstico — engenheiro precisa investigar do zero
- ✗Sem cooldown — mesmo alerta a cada 5 minutos
- ✗Canal de notificação que ninguém monitora
✅ Resumo do Módulo — e da Trilha 2
🎉 Trilha 2 Completa!
Você aprendeu os 6 procedimentos técnicos essenciais: auditoria de 4 eixos, amostragem estratégica, pipeline de unificação, tabelas-resumo com DuckDB, monitoramento com SLA, e painel de alertas. São as receitas que engenheiros experientes aplicam em todo projeto.