No Lab 05 do PostgreSQL Reliability Lab , o cluster detectou a queda do líder, promoveu a réplica, retomou a escrita pelo mesmo endpoint e reintegrou o antigo líder. O mecanismo funcionou, mas operar esse ambiente exige responder a outra classe de perguntas:

O banco está disponível? Quem é o líder? A réplica está atrasada? As conexões estão crescendo? Que erro ocorreu e em qual nó?

O Lab 06 já está disponível no GitHub . Ele acrescenta Prometheus, PostgreSQL Exporter, Grafana, Loki e Promtail ao cluster de alta disponibilidade e cria uma cadeia reproduzível de métricas, logs, visualização e regras de alerta.

O objetivo não é apenas subir uma tela com gráficos. O roteiro automatizado verifica se os sinais saem dos nós PostgreSQL, chegam às ferramentas de observabilidade e podem ser consultados com significado operacional.

Da disponibilidade à explicação

Um healthcheck responde a uma pergunta estreita: determinado processo ou endpoint está acessível agora? Isso é necessário, mas insuficiente para explicar o comportamento de um sistema distribuído.

Neste laboratório, a observabilidade foi dividida em duas fontes complementares:

  • métricas: mostram estado e evolução numérica, como disponibilidade dos exporters, papel dos membros, conexões, transações e diferença de WAL;
  • logs: preservam eventos com contexto, como conexões, checkpoints, erros e consultas que ultrapassam um limite de duração.

O Grafana reúne as duas fontes. O Prometheus armazena as séries temporais e avalia regras. O Loki recebe os logs estruturados. Essa combinação permite partir de uma mudança no dashboard e avançar para os eventos relacionados, sem tratar uma tela verde como prova suficiente de confiabilidade.

Arquitetura do Lab 06

O ambiente executa 13 containers:

CamadaServiçosResponsabilidade
Bancopg1 e pg2PostgreSQL 16 gerenciado pelo Patroni
Coordenaçãoetcd1, etcd2 e etcd3Estado distribuído e eleição do líder
RoteamentohaproxyEndpoint estável para escrita
Coleta de métricasdois PostgreSQL ExportersEstatísticas de cada nó PostgreSQL
Métricas e regrasPrometheusColeta, armazenamento local e avaliação de alertas
Coleta de logsPromtailLeitura e envio dos logs JSON dos dois nós
LogsLokiIndexação e consulta dos eventos
VisualizaçãoGrafanaDashboard e consulta das duas fontes
OperaçãoclientExecução dos testes e comandos do lab

O fluxo principal é:

cliente → HAProxy → líder PostgreSQL ↔ réplica PostgreSQL
                         │                    │
                         ├── métricas ────────┼──→ Prometheus ──┐
                         └── logs JSON ───────┴──→ Loki ────────┤
                                                               ↓
                                                            Grafana

Os exporters se conectam com a role monitor_user, que recebe pg_monitor, sem utilizar o superusuário. O Prometheus também consulta diretamente o endpoint /metrics de cada membro Patroni.

Somente HAProxy, Grafana, Prometheus e Loki publicam portas no host, sempre em 127.0.0.1. APIs do Patroni, etcd, exporters e Promtail permanecem na rede interna do Compose.

Subindo o ambiente

Com Docker Compose e Bash disponíveis:

git clone https://github.com/dirleiflsilva/postgresql-reliability-lab.git
cd postgresql-reliability-lab/labs/06-observability
cp .env.example .env

Substitua no .env todas as senhas de exemplo. Em seguida:

docker compose build
docker compose up -d --wait --wait-timeout 300
bash scripts/check.sh
bash scripts/status.sh

O primeiro build requer acesso à internet e o ambiente precisa de recursos para os 13 containers. O registro publicado foi validado com PostgreSQL 16, Patroni 4.1.0, etcd 3.5.21, PostgreSQL Exporter 0.17.1, Prometheus 3.1.0, Grafana 11.4.0 e Loki/Promtail 3.3.2.

Os acessos locais padrão são:

ServiçoEndereço
PostgreSQL para escrita127.0.0.1:5440
Grafanahttp://127.0.0.1:3000
Prometheushttp://127.0.0.1:9090
Lokihttp://127.0.0.1:3100/ready

No Grafana, o dashboard PostgreSQL Reliability — Overview é provisionado automaticamente dentro da pasta PostgreSQL Reliability Lab.

Métricas do PostgreSQL e do Patroni

Os dois PostgreSQL Exporters expõem estatísticas de cada instância. Isso permite verificar, por exemplo, se ambos estão disponíveis:

pg_up

O endpoint do Patroni complementa essa visão com o papel de cada membro. A consulta abaixo deve apontar exatamente um líder:

sum(patroni_primary)

Para observar atividade na base:

rate(pg_stat_database_xact_commit{datname="appdb"}[1m])

E, para a diferença entre a posição de WAL recebida e reproduzida na réplica:

clamp_min(
  patroni_xlog_received_location - patroni_xlog_replayed_location,
  0
)
and on(node) (patroni_replica == 1)

Essa diferença é expressa em bytes, não em segundos. Ela mostra a distância observada entre recebimento e replay, mas não permite deduzir isoladamente quanto tempo a réplica levará para alcançar o líder.

Logs estruturados do PostgreSQL

O PostgreSQL foi configurado para gravar em jsonlog, com arquivos separados por nó. Entre os eventos habilitados estão conexões, desconexões, checkpoints, esperas por lock e consultas com duração mínima de 250 ms.

O Promtail lê os volumes de log de pg1 e pg2, extrai campos do JSON e adiciona labels como nó, severidade, banco e usuário. No Loki, algumas consultas úteis são:

{job="postgresql"} | json
{job="postgresql", severity="ERROR"} | json
{job="postgresql"} |= "duration:" | json

Labels ajudam a filtrar, mas precisam ser escolhidos com cuidado. Campos com cardinalidade muito alta aumentam o custo do índice. Neste lab, o conteúdo completo continua no evento e somente um conjunto pequeno de dimensões é promovido a label.

Gerando sinais de forma controlada

Um dashboard vazio pode estar corretamente configurado e ainda assim não demonstrar o caminho de coleta. Por isso, o lab inclui um gerador simples:

bash scripts/generate_load.sh 60

Durante 60 segundos, ele executa agregações sobre pedidos e uma espera de 300 ms. A espera ultrapassa deliberadamente log_min_duration_statement = 250, criando eventos previsíveis para consulta no Loki.

O artifício é didático. Em produção, o limite de duração, a amostragem e o conteúdo registrado devem considerar volume, custo e privacidade. Logs de instruções SQL podem conter dados sensíveis.

Alertas: detectar ainda não é notificar

O Prometheus carrega cinco regras:

  • exporter PostgreSQL indisponível;
  • membro Patroni indisponível;
  • ausência de líder observado;
  • mais de 80 conexões em um nó;
  • lag de replicação superior a 16 MiB.

As regras possuem uma duração mínima antes de entrar em estado de alerta, reduzindo reações a oscilações muito breves. Por exemplo, a ausência de líder precisa persistir por 15 segundos, enquanto o lag precisa permanecer acima do limite por um minuto.

Esses valores são didáticos. Eles não representam SLOs e não devem ser transportados diretamente para produção. Limites úteis dependem da capacidade, do baseline, do orçamento de erro e do impacto percebido pelos usuários.

O lab também não inclui Alertmanager. Portanto, comprovar que uma regra foi carregada ou entrou em estado firing não comprova que uma notificação chegou à pessoa responsável. Detecção, roteamento, entrega e resposta são etapas diferentes.

A validação ponta a ponta

O scripts/check.sh não se limita a conferir se os containers estão em execução. Ele valida:

  1. dados, endpoint de escrita e streaming replication;
  2. dois exporters PostgreSQL disponíveis no Prometheus;
  3. exatamente um líder observado por patroni_primary;
  4. carregamento das regras de alerta;
  5. saúde do Loki e do Grafana;
  6. provisionamento do dashboard;
  7. ingestão ponta a ponta de um log identificado por token.

Na última etapa, o script cria um token único dentro de uma consulta com pg_sleep(0.35). Depois, procura esse mesmo token pela API do Loki. Assim, o teste percorre:

consulta → PostgreSQL → arquivo JSON → Promtail → Loki → consulta da evidência

Cada execução bem-sucedida grava um arquivo local em evidence/. O registro de validação publicado documenta a execução de 18/10/2026, que confirmou 100 clientes, 500 pedidos, uma réplica em streaming, os dois exporters, um líder, regras carregadas, dashboard provisionado e o token encontrado no Loki.

Essa evidência demonstra o caminho básico de telemetria no ambiente local. Ela não valida retenção, notificações, carga prolongada nem a disponibilidade das próprias ferramentas de observabilidade.

Observabilidade também pode falhar

Prometheus, Loki e Grafana executam em instância única e armazenam dados localmente. Se um deles parar, parte da visibilidade desaparece justamente quando pode ser mais necessária.

Também não há TLS nas interfaces do lab. Prometheus e Loki não possuem autenticação, e a senha do usuário de monitoramento aparece na configuração resolvida do Compose. A publicação apenas em loopback reduz a exposição no ambiente local, mas não transforma essa configuração em arquitetura de produção.

Outro limite importante está no agente de logs. O Promtail foi mantido pela simplicidade didática e pela compatibilidade com o cenário, mas está em modo de manutenção de longo prazo no ecossistema Grafana. Uma plataforma nova deve avaliar o Grafana Alloy ou outro agente compatível antes de adotar a mesma escolha.

Por fim, a role monitor_user usa pg_monitor. Embora não seja superusuária, ela pode acessar estatísticas e informações de atividade que merecem proteção.

Uma tela verde não encerra a investigação

O Lab 06 acrescenta visibilidade ao cluster do Lab 05: métricas dos dois nós, estado do Patroni, logs estruturados, dashboard provisionado e regras de detecção. Mais importante, acrescenta um teste automatizado que comprova o caminho de um sinal conhecido até sua consulta.

O aprendizado central é que observabilidade não nasce da quantidade de gráficos. Ela depende de sinais que respondam a perguntas operacionais, contexto para investigar mudanças e validação do caminho completo de coleta.

Uma tela verde mostra apenas o que foi medido e entregue naquele instante. Testes de recuperação, alertas exercitados, notificações, runbooks e sinais da aplicação continuam sendo partes separadas da confiabilidade.

Referências