Monitoramento de todas as VPS

API central de leitura para o suporte: CPU, memória, disco, Docker, banco, backups, instâncias, chamadas e webhooks.

O backend do painel de suporte consulta a central, que reúne os servidores já cadastrados no console. Não é necessário distribuir os tokens administrativos das VPS ao painel. Esta API é de leitura; não reinicia serviços nem altera instâncias, limites de chamadas ou webhooks.

Endpoints e autenticação

BaseEndpointCredencial
Central, por exemplo https://wpp.atendro.cloudGET /api/v1/servers/statusAuthorization: Bearer <TOKEN_MONITORAMENTO>
CentralGET /api/v1/servers/{server}/statusMesmo token de monitoramento
API de cada VPSGET /v1/system/statusHeader admintoken, usado internamente pela central

server é o nome cadastrado no console. O cadastro existente determina as VPS consultadas; esta API não aceita URLs arbitrárias. O token da central fica em CONSOLE_MONITORING_TOKEN ou, no Compose, ATENDROZAP_CONSOLE_MONITORING_TOKEN. Use um segredo aleatório de pelo menos 32 caracteres, distinto dos tokens das VPS. Ausente: HTTP 503 monitoring_disabled. Inválido: HTTP 401. Servidor não cadastrado: HTTP 404 server_not_found.

O token é exclusivo destes GETs. Login do console, cookies, token de instância e query string não o substituem. Guarde-o no backend do suporte, nunca no bundle, localStorage ou parâmetros da URL. A API não habilita CORS público.

Exemplo de consumo no backend Node, sem imprimir credenciais:

js
const response = await fetch(
  `${process.env.ATENDROZAP_CENTRAL_URL}/api/v1/servers/status`,
  {
    headers: { Authorization: `Bearer ${process.env.ATENDROZAP_MONITORING_TOKEN}` },
    signal: AbortSignal.timeout(10_000),
    redirect: 'error',
  },
);
if (!response.ok) throw new Error(`monitoring_http_${response.status}`);
const fleet = await response.json();
// Entregue fleet à rota autenticada do seu painel de suporte.

Contrato completo: OpenAPI da central. O endpoint de cada VPS está no OpenAPI principal.

Como ler a resposta

schemaVersion começa em 1. servers inclui também servidores offline, sem suporte à nova versão ou com falhas parciais. A ordem é pelo nome cadastrado.

CampoSignificado
generatedAtMomento da resposta da central, em UTC
cacheSecondsReutilização interna por até 15 segundos
summaryContagem total, online, offline, indisponíveis e por saúde
servers[].serverNome da VPS no cadastro central
observedAtMomento da tentativa mais recente de consultar a VPS
lastSuccessAtÚltima resposta válida observada; null se ainda não houve
availabilityonline, offline, unauthorized, unsupported, invalid_configuration, invalid_response, stale, unavailable ou cancelled
healthok, warning, critical ou unknown
latencyMillisecondsTempo até os headers HTTP da VPS; null quando indisponível
dataStaleA resposta de data é uma leitura anterior, não uma medição atual
dataSnapshot tipado da VPS, ou null sem leitura válida
alerts[]Código estável e gravidade, sem erros brutos ou dados privados

HTTP 200 significa que a consulta central foi executada; não significa que todas as VPS estão saudáveis. Use availability, health, dataStale e os estados de cada seção. Um erro de autenticação da VPS não é ausência de carga. Falhas não propagam corpos, headers, endereços ou tokens do servidor remoto.

As duas rotas compartilham cache. Há no máximo oito consultas simultâneas e cinco segundos por coleta, incluindo a espera por vaga. Muitas consultas de suporte ao mesmo servidor se unem em uma coleta. Novos cadastros aparecem na próxima consulta; alterações de URL/token invalidam o cache correspondente. Leituras anteriores ficam somente em memória e se perdem ao reiniciar a central.

Métricas disponíveis em data

SeçãoMedições e interpretação
host.snapshot.cpuCPUs lógicas, uso, espera por I/O e steal, em porcentagem
host.snapshot.loadLoad de 1/5/15 minutos e load dividido por CPUs lógicas
host.snapshot.memoryRAM total, disponível, usada e percentual; considera MemAvailable
host.snapshot.swapTotal, livre, usada e percentual
host.snapshot.rootFilesystemDisco total, livre, disponível, reservado, ocupado; inodes livres e usados
host.snapshot.networkContadores e bytes/s de recepção/transmissão; inclui interfaces virtuais não loopback
host.snapshot.diskIOI/O e ocupação do dispositivo da raiz; evita somar disco e partição
host.snapshot.uptimeSecondsTempo ligado da VPS
host.snapshot.operations.dockerPor papel api/db/backup/console/caddy: containers, em execução, reiniciando, OOM, reinícios e healthcheck
host.snapshot.operations.storageBytes lógicos, quantidade e idade de arquivos de WAL, backups, gravações e diagnóstico; WAL completo cru, gzip, incompleto e auxiliares separados
host.snapshot.operations.backupVerificationMarcador da última execução de pg_verifybackup; estado e idade da verificação
databaseDisponibilidade, tamanho do banco e pool de conexões da API
database.archiverEstado do arquivamento, quantidade pendente, tamanho de pg_wal, sucessos/falhas e timestamps
workload.instancesContagens por tipo/estado, leases desta VPS, estados conectados sem lease, vagas de chamadas configuradas e limite de sessões do worker
workload.callsChamadas persistidas abertas, ativas/tocando/conectando/vídeo, excluindo leases expirados ou transferidos do total live
workload.webhooksFila pendente, idade do evento mais antigo, retentativas, eventos mortos e destinos falhando/pausados
processUptime, goroutines e memória do runtime Go da API; não é a RAM da VPS

host.status pode ser ok/degraded/stale/unavailable. O snapshot traz a hora original de coleta e sua validade. Métricas sem base de comparação, inclusive CPU/rede no primeiro ciclo e após reset, são null. Coleta parcial não converte ausência em zero. Tamanhos dos diretórios são bytes lógicos; disco disponível vem do filesystem. Tráfego agregado inclui interfaces Docker: não serve como fatura de tráfego externo. Falta de healthcheck aparece como tal.

Instâncias e webhooks usam scope: database. Chamadas usam scope: worker e source: database_snapshot; não são uma prova de mídia RTP nem de qualidade da chamada. Se duas VPS compartilham banco, não some as contagens de escopo database. callSlotsConfigured é configuração, não capacidade homologada. A central não estima quantas chamadas uma VPS aguenta a partir desses números.

Um backup verificado não prova cópia fora da VPS nem uma cadeia PITR completa. Sem o marcador de verificação, a situação é desconhecida, mesmo que existam arquivos de backup no diretório. O histórico de falhas do archiver é cumulativo; blocked exige falha mais recente que o sucesso e segmentos pendentes.

Alertas e painel

O painel pode começar com cartões de VPS, barras de CPU/RAM/disco, estado dos serviços, arquivamento do WAL, idade do backup, instâncias e chamadas ativas. Atualize a cada 30 segundos. Preserve indicação de leitura antiga e exiba — para null, em vez de zero. Um erro global da central deve marcar o painel como desatualizado, sem limpar todos os servidores existentes.

Limiares iniciais da central:

MedidaAvisoCrítico
Disco e inodes ocupados85%95%
RAM ocupada85%95%
CPU ocupada85%98%
CPU steal10%25%
Verificação de backup antiga—Mais de 36 horas

Banco indisponível, WAL bloqueado e serviço parado/reiniciando/unhealthy/OOM geram alerta crítico. Dados incompletos, WAL parcial e fila de webhook com mais de cinco minutos geram aviso. Os limiares avaliam snapshots; para notificações, o suporte deve exigir persistência em várias amostras e deduplicar alertas. Esta implementação não envia mensagens nem instala um sistema de notificações.

Para gráficos históricos, armazene as amostras no backend do suporte usando server e a hora original sampledAt; não duplique amostras vindas do cache. A API fornece estado atual e última leitura válida, não séries temporais.

Instalação

  1. Preparar a revisão pelo fluxo deploy/ship.sh HOST REV. O build exporta host-health e wal-archive estáticos para /opt/atendrozap/releases/REV/ops. Ative a revisão com sh deploy/host-health/install-ops.sh REV no host; o preparo do build por si só não troca os executáveis em uso.
  2. Instalar os arquivos de deploy/host-health e executar install.sh no host. O serviço systemd coleta a cada 15 segundos e escreve arquivo privado 0600, dono UID/GID 65532, em /opt/atendrozap/health/status.json.
  3. O Compose monta esse diretório somente para leitura na API. Configure ATENDROZAP_SYSTEM_STATUS_HOST_FILE=/host-health/status.json e, opcionalmente, ATENDROZAP_SYSTEM_STATUS_HOST_MAX_AGE=3m (15s a 15m). O prazo efetivo é o menor entre esse teto e validForSeconds do snapshot; com coleta a cada 15 segundos, o coletor declara validade de 45 segundos.
  4. Configure o token de monitoramento privado na central. Publique API e console na janela autorizada; recriar a API afeta brevemente as sessões de mensagens e chamadas. Recriar PostgreSQL para usar o novo archive_command é um passo distinto e deve ser coordenado.
  5. Confira cada VPS pelo novo endpoint e as ausências parciais antes de considerar o painel operacional. VPS antigas aparecem como unsupported.

O coletor roda no host Linux, acessa /proc e consulta apenas campos permitidos do Docker. O socket Docker não é montado na API. Reinicie somente o coletor após mudar volumes/papéis para atualizar os diretórios descobertos. macOS e execução do coletor dentro de container são explicitamente indisponíveis.