evobits

evobits · especificação de integração · sensor de contrato de saúde

Contrato de saúde para o status agregado

Um endpoint só, de leitura, que diz o que está bem e o que não está dentro da aplicação parceira. Este documento é o que precisa ser implementado, e como saber que ficou pronto.

Para
Times de produto de aplicações parceiras integradas a uma página de status do evobits
Endpoint
GET /internal/health
Quem consulta
A sonda do evobits, de minuto em minuto
IP de origem
165.245.130.16

Copia esta especificação inteira em Markdown, para colar no ChatGPT, no Claude, no Gemini ou no assistente que vocês usam.

Exemplo de prompt
Preciso implementar um endpoint de saúde na nossa aplicação, seguindo a
especificação que vou colar abaixo.

Nossa stack: (descreva aqui: linguagem, framework, banco, fila, servidor web).

Leia a especificação inteira e:
1. gere o código do endpoint na nossa stack;
2. implemente os itens esperados para a NOSSA aplicação, e só esses;
3. inclua o cache, o teto de tempo e o 404 sem token válido;
4. escreva os testes do checklist de aceite.

<COLE AQUI O TEXTO COPIADO PELO BOTÃO "COPIAR PARA IA">

01Por que este contrato existe

Uma página de status do evobits pode agregar, além dos componentes que o próprio evobits monitora, aplicações de parceiros: sistemas de terceiros que um cliente depende e quer expor no mesmo painel de saúde. Monitorar essas aplicações só de fora, batendo numa URL pública e olhando se responde, enxerga o serviço morto, mas não enxerga o serviço vivo e quebrado: banco fora, fila entupida, certificado vencendo, provedor externo recusando. Quando isso acontece, o usuário final sente e a página de status continua verde, que é o pior cenário possível para uma página de status.

O que pedimos à aplicação parceira é um endpoint só, de leitura, que responda o que está bem e o que não está dentro dela. O evobits lê esse endpoint pelo sensor de tipo contrato_saude e traduz para o semáforo público.

02O endpoint e as oito regras

GET /internal/health
X-NW-Status-Token: <token>

O nome do cabeçalho é histórico (o protocolo nasceu antes do evobits existir como produto próprio) e fica assim de propósito: é o que sondas já implantadas mandam, e trocar o nome quebraria integrações em produção sem necessidade. Cada regra abaixo vem com o motivo, porque o motivo é o que decide os casos que a regra não cobre.

  1. 01

    Sem token válido, responde 404

    Não 401 e não 403. É para não anunciar que a rota existe.

  2. 02

    Com token válido, responde sempre 200 e com corpo

    Mesmo quando tudo estiver ruim. Degradação nunca pode virar 5xx: proxy, WAF e nginx mascaram 5xx e aí a gente perde justamente a informação de o que quebrou. Código diferente de 200 só quando o processo realmente não conseguiu responder.

  3. 03

    Três estados, só esses

    ok, atencao e ruim. Vale para o estado geral e para cada item.

    • ok tudo dentro do esperado
    • atencao fora do normal, ainda serve
    • ruim quebrado ou inalcançável
  4. 04

    Cada checagem se protege sozinha

    Se a checagem do banco estourar, aquele item vira ruim com um campo erro, e os outros itens continuam sendo respondidos. Um item quebrado não pode derrubar a resposta inteira.

  5. 05

    Teto de 3 segundos para montar a resposta completa

    O sensor de contrato de saúde desiste em 5.

  6. 06

    Cache interno de 15 a 30 segundos

    A sonda bate de minuto em minuto, mas monitor externo e curiosidade humana somam. O cache é o que impede a checagem de saúde de virar carga em cima da aplicação parceira.

  7. 07

    Pode ter número aqui

    É rota interna, autenticada, servidor para servidor. Quem decide o que vira público é o evobits, não a aplicação parceira. Nada do que vier aqui é publicado cru.

  8. 08

    O GET /health raso que já existe continua como está

    Este é um endpoint novo, ao lado, não uma substituição.

03O formato da resposta

{
  "app": "minha-aplicacao",
  "instancia": "api.minhaempresa.com",
  "versao": "2.3.1",
  "geradoEm": "2026-09-23T11:28:42.267Z",
  "estado": "atencao",
  "itens": [
    { "chave": "banco",       "estado": "ok",      "medida": { "latenciaMs": 12 } },
    { "chave": "redis",       "estado": "ok",      "medida": { "latenciaMs": 2 } },
    { "chave": "filas",       "estado": "atencao", "medida": { "waiting": 420, "failed": 3, "dlq": 0 } },
    { "chave": "disco",       "estado": "ok",      "medida": { "livrePct": 41 } },
    { "chave": "memoria",     "estado": "ok",      "medida": { "livrePct": 22 } },
    { "chave": "processos",   "estado": "ok",      "medida": { "vivos": 6, "esperados": 6 } },
    { "chave": "certificado", "estado": "ok",      "medida": { "diasParaVencer": 63 } },
    { "chave": "provedor_pagamento", "estado": "ruim", "medida": { "latenciaMs": 0 }, "erro": "timeout" }
  ]
}
Campos do envelope
CampoObrigatórioO que é
appsimIdentificador curto e fixo da aplicação, em minúsculas
instanciasimHost ou nome da instância que respondeu
versaosimVersão em execução, para sabermos se o deploy pegou
geradoEmsimISO 8601 em UTC, o instante da amostra, não o do cache
estadosimO pior estado entre os itens, resumido
itenssimLista, cada item com chave, estado e medida
errosó quando falhaTexto curto, na raiz do item que falhou

04Vocabulário de itens

Item que não existe na aplicação simplesmente não entra na lista. Não invente item para preencher.

Use o vocabulário comum quando o conceito for comum, porque é isso que deixa o evobits tratar toda aplicação parceira do mesmo jeito: banco, redis, filas, disco, memoria, processos, certificado.

Quando o item for específico da aplicação, a chave é livre. Só pedimos que seja estável entre deploys, para o histórico do sensor não quebrar a cada versão nova.

ChaveO que medir
bancoConexão viva e latência de um SELECT 1 (ou equivalente)
redisConexão viva e latência de um PING, se houver
filasPendentes, falhados e fila morta, se houver fila
discoPercentual livre da partição da aplicação
memoriaPercentual livre
processosQuantos processos deveriam estar vivos e quantos estão
certificadoDias até o certificado do host vencer

Se a aplicação rodar em processos separados, o ideal é um endpoint por processo com porta HTTP. Para worker e job de cron, que não têm porta para sondar, veja a seção 06.

05Token e acesso

  1. 01

    Token por aplicação, gerado pelo time parceiro

    Pelo menos 32 caracteres aleatórios, guardado no .env do servidor. Nunca em arquivo versionado.

  2. 02

    O token chega por canal privado, combinado com o time de operação do evobits

    Não vai em e-mail em texto claro junto com a URL.

  3. 03

    Quem consulta é sempre o mesmo IP: 165.245.130.16

    Se a aplicação parceira quiser restringir a rota por IP de origem, além do token, melhor ainda. O evobits prefere assim.

  4. 04

    Se o token precisar rodar, avisem antes

    A troca é um campo no sensor de contrato do lado do evobits e leva um minuto. Mas sem aviso a aplicação parceira aparece fora do ar na página pública.

06Alternativa para o que não tem porta HTTP

Worker e job de cron não têm como responder a uma sonda. Para esses, o caminho é o inverso: o processo avisa que está vivo.

POST https://<slug>.status.evobits.com.br/api/heartbeat/<chave>
X-NW-Status-Token: <token>

O processo chama isso a cada ciclo. Se o carimbo passar da idade combinada, o evobits marca aquele componente como ruim. A chave e o token são fornecidos pelo time de operação.

07Como saber que está entregue

Checklist objetivo, e é exatamente o que o evobits confere do lado dele.

  1. 01GET /internal/health sem header de token responde 404.
  2. 02GET /internal/health com token errado responde 404.
  3. 03Com token certo responde 200 e o envelope completo.
  4. 04Com uma dependência derrubada de propósito, o banco por exemplo, a resposta continua 200, o item correspondente vem ruim com erro, e os demais itens continuam preenchidos.
  5. 05Duas chamadas seguidas dentro de 15 segundos devolvem o mesmo geradoEm, provando que o cache está de pé.
  6. 06A resposta completa volta em menos de 3 segundos.
  7. 07GET /health, o raso que já existia, continua respondendo como antes.

08O que fazemos com isso, e o que nunca vira público

O evobits lê esse endpoint de minuto em minuto e traduz para um semáforo por item, dentro da página de status do cliente. A página pública não mostra número, não mostra nome de host e não mostra nome de cliente: ela mostra operacional, degradado ou fora do ar. Os números crus ficam só no painel administrativo do evobits, autenticado.

Além disso o semáforo público só muda depois de duas amostras ruins seguidas, para que uma sonda perdida não pinte a página de vermelho.

Dúvida sobre qualquer ponto acima, falem com o time de operação do evobits antes de implementar. É mais barato alinhar o formato agora do que depois de pronto.