📊 Observabilidade & SLA¶
Como monitoramos a saúde do ecossistema de dados e garantimos a disponibilidade para o negócio.
🩺 Health Check Automatizado¶
O principal instrumento de observabilidade é a DAG daily_health_check, que roda diariamente às 7h (horário de Brasília) no Composer Lakehouse e envia um relatório gerencial por e-mail com o status completo do ambiente.
Exemplo do Relatório (E-mail)¶

Exemplo real do relatório enviado por e-mail (05/03/2026)
Fluxo da DAG¶
graph TD
A[daily_health_check] --> B[check_composer_status]
A --> C[check_failed_tasks]
A --> D[get_data_quality]
A --> E[get_gcp_costs]
A --> F[get_top_bq_jobs]
A --> G[get_stale_tables]
A --> H[check_critical_tables_by_company]
A --> I[check_full_load_dags]
B --> J[generate_executive_report]
C --> J
D --> J
E --> J
F --> J
G --> J
H --> J
I --> J
J --> K[send_email_task]
style A fill:#a6216c,color:#fff
style J fill:#1565c0,color:#fff
style K fill:#28a745,color:#fff
Seções do Relatório¶
O Health Check coleta e apresenta 8 métricas em um relatório HTML:
| # | Seção | O que Monitora | Fonte |
|---|---|---|---|
| 1 | Status do Composer | ON/OFF do Composer Lakehouse (único, orquestra Lakehouse, CDP, Operações, Pessoas) | Composer API |
| 2 | DAGs Falhadas | Quantidade de DAGs com falha nas últimas 24h + % de sucesso por ambiente | Airflow REST API |
| 3 | Qualidade de Dados (Soda) | Alertas e erros do Soda Core por projeto | BigQuery (lavoro_logs.soda_logs) |
| 4 | Custos GCP | Custo diário + variação D-1/D-2 + Top 5 serviços + acumulado mensal | BigQuery (all_billing_data.CONTROLE_CUSTOS_GCP) |
| 5 | Top 3 Jobs BigQuery | Jobs com mais TB processados no último dia | BigQuery (all_billing_data.CONTROLE_CUSTOS_BQ_QUERYS) |
| 6 | Tabelas Desatualizadas | Tabelas fato_* e dim_* nos 5 datasets Gold que não atualizaram há >1 dia |
BigQuery (__TABLES__) |
| 7 | Lançamentos Críticos | Empresas com faturamento/pedido sem lançamentos há >2 dias úteis | BigQuery (gold_lakehouse.fato_faturamento) |
| 8 | DAGs Full Load | DAGs com _full no nome (indicador de carga completa em execução) |
Airflow REST API |
Indicadores de Status¶
O relatório calcula automaticamente um status geral baseado nos problemas encontrados:
| Status | Condição | Ação |
|---|---|---|
| 🟢 SAUDÁVEL | Nenhum problema detectado | Nenhuma ação necessária |
| 🟡 ATENÇÃO | 1-2 pontos de atenção | Investigar nas próximas horas |
| 🔴 CRÍTICO | 3+ problemas detectados | Ação imediata necessária |
Critérios de alerta:
- Composer(s) offline
- ≥3 DAGs falhadas
- Erros de qualidade de dados (Soda)
- Tabelas Gold sem atualização há >2 dias
KPIs do Dashboard (Cards)¶
O topo do relatório exibe 4 KPIs em destaque:
| KPI | Descrição | Meta |
|---|---|---|
| Disponib. | Composers online / total | 4/4 |
| % Sucesso Cargas | DAGs sem falha / total de DAGs | >95% |
| Qualidade (Erros DQ) | Erros Soda Core do dia | 0 |
| Var. Custo | Variação % do custo GCP vs dia anterior | <10% |
Configuração¶
| Parâmetro | Valor |
|---|---|
| DAG ID | daily_health_check |
| Schedule | 0 10 * * * (7h Brasília) |
| Repositório | lavoro-lakehouse |
| Arquivo | dags/daily_health_check.py |
| Destinatários | Time de Dados (via e-mail) |
| Threshold custo diário | R$ 1.167/dia (meta R$ 35.000/mês) |
🏗️ Stack de Monitoramento¶
graph TB
subgraph Fontes["📡 Fontes de Dados"]
A1[Cloud Composer]
A2[BigQuery]
A3[GitHub Actions]
end
subgraph Monitoramento["🔍 Monitoramento"]
B1[Cloud Monitoring]
B2[Cloud Logging]
B3[Health Check DAG]
end
subgraph Alertas["🔔 Alertas"]
C1[E-mail Health Check]
C2[Slack]
end
A1 --> B1
A1 --> B3
A2 --> B1
A2 --> B3
A3 --> B2
B1 --> C2
B3 --> C1
style Fontes fill:#e3f2fd,stroke:#1565c0
style Monitoramento fill:#fff3e0,stroke:#ef6c00
style Alertas fill:#fce4ec,stroke:#c62828
| Ferramenta | Finalidade | Acesso |
|---|---|---|
| Health Check DAG | Relatório diário consolidado por e-mail | Airflow (Composer Lakehouse) |
| Cloud Monitoring | Métricas de Composer, BigQuery e VMs | GCP Console |
| Cloud Logging | Logs centralizados de todos os serviços | GCP Console |
| GitHub Actions | Status de CI/CD e deploys | GitHub |
🎯 SLAs por Camada¶
Prazos máximos para disponibilidade dos dados após a execução do pipeline.
| Camada | SLA | Horário de Referência | Impacto se Atrasar |
|---|---|---|---|
| Bronze | Dados brutos disponíveis até 6h | Após início da DAG | Silver e Gold atrasam |
| Silver | Dados transformados até 7h | Após conclusão da Bronze | Gold e dashboards atrasam |
| Gold | Dados de consumo até 8h | Após conclusão da Silver | Dashboards desatualizados |
| Health Check | Relatório enviado até 7h30 | Após conclusão dos pipelines | Sem visibilidade do status |
Janela de Execução
A maioria das DAGs são agendadas para iniciar entre 4h e 6h da manhã, garantindo que os dados Gold estejam prontos antes do horário comercial. O Health Check roda às 7h para capturar o status final.
gantt
title Janela de Execução Diária
dateFormat HH:mm
axisFormat %H:%M
section Pipeline
Bronze (Extração) :a1, 04:00, 2h
Silver (Transformação):a2, after a1, 1h
Gold (Consumo) :a3, after a2, 1h
section Monitoramento
Health Check DAG :a4, 07:00, 30min
E-mail Enviado :milestone, 07:30, 0h
🔍 Queries Úteis de Monitoramento¶
Verificar Freshness das Tabelas Gold¶
SELECT
dataset_id AS dataset,
table_id AS tabela,
DATE(TIMESTAMP_MILLIS(last_modified_time)) AS ultima_atualizacao,
ROUND(TIMESTAMP_DIFF(
CURRENT_TIMESTAMP(),
TIMESTAMP_MILLIS(last_modified_time), HOUR
) / 24, 1) AS dias_sem_atualizar
FROM `driven-strength-374020.gold_lakehouse.__TABLES__`
WHERE (table_id LIKE 'fato_%' OR table_id LIKE 'dim_%')
AND DATE(TIMESTAMP_MILLIS(last_modified_time)) < CURRENT_DATE() - 1
ORDER BY last_modified_time ASC
Volume de Dados Processados por Dia¶
SELECT
DATE(creation_time) AS data,
SUM(total_bytes_processed) / POW(1024, 3) AS gb_processados,
COUNT(*) AS total_queries
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE DATE(creation_time) >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
GROUP BY data
ORDER BY data DESC
Alertas Soda Core por Projeto¶
SELECT
UPPER(REGEXP_EXTRACT(dataset_id, r'_(.*)')) AS projeto,
COUNTIF(UPPER(categoria) = 'ALERTA') AS alertas,
COUNTIF(UPPER(categoria) = 'ERRO') AS erros
FROM `driven-strength-374020.lavoro_logs.soda_logs`
WHERE DATE(created_at) = CURRENT_DATE() - 1
GROUP BY ALL
📖 Links Úteis¶
- Cloud Monitoring - Composer — Dashboards e alertas
- Cloud Logging — Logs centralizados
- BigQuery Admin — Quota e jobs
- Runbook de Incidentes — O que fazer quando algo falha
📅 Atualizado em Março 2026