ZAP-API
PreçosCasos de UsoBlogDocsLogin
Começar grátis
  1. Blog
  2. Observabilidade em produção: logs, alertas e métricas de instância WhatsApp
Observabilidade

Observabilidade em produção: logs, alertas e métricas de instância WhatsApp

Como montar um stack completo de observabilidade para integrações WhatsApp em produção: logs estruturados, métricas de saúde, alertas proativos e dashboards.

03 de junho de 2026·14 min de leitura·Equipe Editorial ZAP API

Uma equipe de DevOps acordou com 47 chamados pendentes. O dia anterior tinha sido normal: deploy às 14h, smoke test passou, ninguém notou nada. Mas durante a madrugada, uma das instâncias críticas (a do cliente que mais factura) tinha desconectado às 3h12. Reconectou sozinha às 3h45, mas as mensagens enfileiradas durante esses 33 minutos não foram entregues — porque o circuit breaker abriu, descartou os jobs com mais de 30 minutos de idade. Resultado: 1.247 mensagens perdidas, cliente furioso, gestor pedindo explicação.

O culpado não foi o bug em si. Bug em sistema distribuído acontece. O culpado foi a falta de observabilidade: ninguém soube que algo estava errado até o cliente reclamar. Sem logs estruturados, métricas e alertas, sua aplicação está cega — você só descobre o problema quando ele virou crise. Este guia mostra como montar stack completo de observabilidade para integrações WhatsApp em produção, do log básico até dashboards Grafana e alertas Slack.

Os 3 pilares

Observabilidade não é só "ter logs". É a combinação de três coisas:

  • Logs: evento textual com contexto. Útil para debug pontual ("o que aconteceu com a mensagem msg_abc?")
  • Métricas: números agregados por janela de tempo. Útil para tendência ("taxa de erro subiu nos últimos 15min?")
  • Alertas: regras que disparam ação humana ou automática quando métrica viola limite

Faltar um dos três cega a aplicação. Logs sem métricas = você acha bug, mas não sabe se está espalhado. Métricas sem alerta = você tem dashboard bonito mas ninguém olha. Alerta sem log = você sabe que algo quebrou mas não consegue debugar.

Logs estruturados em JSON

Texto livre é inútil em escala. JSON estruturado é parseável, indexável e filtrável.

// ❌ Ruim
console.log("Mensagem enviada para 5511999999999");

// ✅ Bom
logger.info({
  event: "message.sent",
  instanceId: "inst_abc123",
  to: "5511999999999",
  messageId: "msg_xyz789",
  bytes: 142,
  durationMs: 87,
});

Bibliotecas: pino (Node.js, mais rápida), winston (mais features). Saída direto pra stdout — Docker captura e envia pra agregador (Loki, ELK, Datadog).

Endpoints de observabilidade da ZAP API

A ZAP API expõe 3 endpoints prontos pra você consumir:

  • GET /v1/instances/:id/health — health score 0-100 + flags
  • GET /v1/diagnostics/agent-snapshot — métricas plataforma autenticadas por X-Diagnostic-Token
  • GET /v1/super-admin/summary?window=24h — totais agregados com sparklines

Dashboard Node.js consumindo todos os endpoints

import axios from "axios";
import express from "express";

const ZAP = axios.create({
  baseURL: "https://api.zap-api.tech/v1",
  headers: {
    Authorization: `Bearer ${process.env.ZAP_TOKEN}`,
    "X-Diagnostic-Token": process.env.ZAP_DIAGNOSTIC_TOKEN,
  },
});

const app = express();

app.get("/dashboard", async (req, res) => {
  const [summary, snapshot, instances] = await Promise.all([
    ZAP.get("/super-admin/summary?window=24h"),
    ZAP.get("/diagnostics/agent-snapshot"),
    ZAP.get("/instances"),
  ]);

  const healths = await Promise.all(
    instances.data.map((i) => ZAP.get(`/instances/${i.id}/health`).then((r) => r.data))
  );

  res.json({
    plataforma: summary.data,
    sistema: snapshot.data,
    instancias: healths,
  });
});

app.listen(4000);

Alertas: do silêncio ao Slack

Regras simples cobrem 80% dos casos. Cron a cada 5 minutos checa, dispara webhook Slack se algo está errado.

import cron from "node-cron";
import axios from "axios";

cron.schedule("*/5 * * * *", async () => {
  const instances = await ZAP.get("/instances");

  for (const inst of instances.data) {
    const health = await ZAP.get(`/instances/${inst.id}/health`);

    if (health.data.score < 70) {
      await axios.post(process.env.SLACK_WEBHOOK_URL, {
        text: `⚠️ ${inst.name} score ${health.data.score}/100 — ${health.data.flags.join(", ")}`,
      });
    }

    if (inst.waStatus !== "CONNECTED" && inst.disconnectedSince) {
      const minsOff = Math.floor((Date.now() - new Date(inst.disconnectedSince)) / 60000);
      if (minsOff > 10) {
        await axios.post(process.env.SLACK_WEBHOOK_URL, {
          text: `🔴 ${inst.name} desconectada há ${minsOff}min`,
        });
      }
    }
  }
});

Custom exporter para Prometheus / Grafana

Quando você tem stack Prometheus rodando, exporter custom pluga métricas direto no scrape.

import express from "express";
import client from "prom-client";

const register = new client.Registry();
client.collectDefaultMetrics({ register });

const messagesSent = new client.Counter({
  name: "zap_messages_sent_total",
  help: "Total messages sent",
  labelNames: ["instance"],
  registers: [register],
});

const instanceScore = new client.Gauge({
  name: "zap_instance_health_score",
  help: "Health score 0-100",
  labelNames: ["instance"],
  registers: [register],
});

// Atualiza métricas a cada 30s
setInterval(async () => {
  const instances = await ZAP.get("/instances");
  for (const inst of instances.data) {
    const health = await ZAP.get(`/instances/${inst.id}/health`);
    instanceScore.set({ instance: inst.name }, health.data.score);
  }
}, 30_000);

// Webhook que recebe message.sent e incrementa
app.post("/webhook/zap", express.json(), (req, res) => {
  if (req.body.type === "message.sent") {
    messagesSent.inc({ instance: req.body.instanceName });
  }
  res.status(200).send("ok");
});

app.get("/metrics", async (req, res) => {
  res.set("Content-Type", register.contentType);
  res.end(await register.metrics());
});

app.listen(9090);

Configure Prometheus para fazer scrape em http://exporter:9090/metrics. Grafana puxa do Prometheus e renderiza dashboards.

SLI / SLO / SLA: a diferença

  • SLI (Service Level Indicator): métrica observada — ex: "% mensagens entregues em até 30s"
  • SLO (Service Level Objective): meta interna — ex: "99,5% das mensagens entregues em 30s"
  • SLA (Service Level Agreement): contrato com cliente — ex: "99,0% ou crédito de 10%"

SLO é interno e mais rigoroso que SLA — se você fica em SLO, está dentro do SLA com folga. Defina SLO por SLI crítico: latência de envio, taxa de entrega, uptime de instância.

Anti-padrões de observabilidade que te deixam cego

Ter logs não significa ter observabilidade. Esses erros são comuns mesmo em times experientes:

  • Log sem correlação: cada serviço loga com IDs próprios, mas não existe traceId comum que amarre a jornada. Você sabe que a mensagem falhou, mas não consegue rastrear em qual hop. Solução: gere traceId no ponto de entrada e propague em todos os serviços downstream via header X-Trace-Id.
  • Alerta que ninguém lê: canal Slack com 200 alertas por dia que todo mundo silenciou. Alerta sem confiança não vale nada — pior que alerta falso é alerta ignorado. Revise regras mensalmente, prune alertas que nunca geraram ação real.
  • Dashboard sem contexto de negócio: gráfico de "mensagens enviadas" sem comparação com meta do dia não diz nada. Adicione linha de target: se você precisa enviar 10k mensagens por dia, dashboard mostra progresso vs meta. Métrica sem alvo é decoração.
  • Log de sucesso sem log de falha estruturado: logar só o que funciona. Quando algo falha, o log é um erro genérico do Express. Defina um schema fixo para erros: {event: "message.send_failed", instanceId, to, errorCode, errorMessage, attempt}. Erro estruturado é pesquisável; stack trace cru não é.
  • Alerta só em produção: staging sem alerta significa que problemas chegam em produção sem aviso prévio. Mantenha o mesmo stack de observabilidade em staging — alertas com threshold mais permissivo, mas existentes.

Runbook: o que fazer quando alerta dispara

Alerta sem runbook é pânico documentado. Para cada alerta recorrente, documente 5 linhas:

// Exemplo de runbook para "instância desconectada > 10min"
const RUNBOOK_DISCONNECTED = {
  alerta: "Instância desconectada há > 10 minutos",
  causas: [
    "Celular do cliente foi para airplane mode ou desligou",
    "WhatsApp no celular foi forçado a fechar pelo SO",
    "Sessão expirou por inatividade",
    "QR code scaneado por outro dispositivo (sessão roubada)",
  ],
  passos: [
    "1. Checar GET /v1/instances/:id/health — olhar flags",
    "2. Se waStatus=QR_REQUIRED: enviar mensagem WhatsApp pro cliente com link de reconexão",
    "3. Se waStatus=CONNECTING há > 2 min: POST /v1/instances/:id/disconnect + connect",
    "4. Se reconnect falhou 3x: escalar para cliente via email com ticket",
    "5. Registrar incidente se mais de 3 instâncias afetadas simultaneamente",
  ],
  escalacao: "Se não resolver em 30min → PagerDuty on-call",
};

Com runbook, on-call de plantão às 3h da manhã segue lista e resolve. Sem runbook, cada incidente é reinventar a roda sob pressão.

FAQ

Qual o stack mínimo viável para uma equipe pequena?

Pino para logs (stdout) + Better Stack ou Logtail para agregação ($0-29/mês) + cron Node.js consumindo ZAP API endpoints + webhook Slack para alerta. Custa entre $0 e $50/mês e cobre 80% dos casos. Não precisa Prometheus/Grafana até atingir 10+ instâncias. A ordem de prioridade é: (1) logs estruturados — sem custo além de stdout; (2) alerta básico para instância desconectada — 2h de dev; (3) dashboard de métricas — só depois que os dois anteriores estiverem estáveis. Equipes que inverteram essa ordem ficaram com dashboards bonitos e instâncias caindo sem ninguém saber.

Quanto custa observabilidade em produção real?

Para 10-50 instâncias, $50-200/mês cobre logs (Loki/Logtail), métricas (Grafana Cloud free tier ou Prometheus self-hosted), alerta (Slack grátis). Para 100+ instâncias, Datadog/New Relic ($150-500/mês) escala melhor mas custa mais. Self-hosted (Prometheus + Grafana + Loki) é gratuito mas exige 2-4h/semana de manutenção de infraestrutura — considere o custo de oportunidade. Regra prática: até $200/mês de plataforma de observabilidade é justificado para qualquer negócio que tenha cliente pagando.

Como evitar alertas falsos positivos?

Três regras: (a) persistência — alerta só dispara se condição persistir por X minutos (ex: score < 70 por 10min, não 1 ponto isolado); (b) cooldown — não realertar pelo mesmo problema em 1h; (c) severidade — separar warning (Slack canal-monitor) de critical (Slack canal-incident + PagerDuty). Além disso, faça "alerta review" mensal: liste todos os alertas que dispararam no mês, qual % gerou ação real, qual % foi falso positivo. Se algum alerta tem > 50% de falso positivo, ajuste threshold ou elimine.

Quanto tempo manter logs?

Logs operacionais: 30-90 dias. Logs de auditoria (quem fez o quê): 1-7 anos (depende da regulação — LGPD recomenda mínimo necessário; alguns setores têm obrigação de 5 anos). Logs de payload de webhook: 7-30 dias (LGPD — não acumular dado de mensagem de cliente sem necessidade). Configure rotação automática. Dica: comprimido, log JSON de 1 dia em produção média ocupa 5-50 MB — custo de storage é irrisório comparado ao valor de ter o log disponível quando necessário.

Como organizar on-call?

Para equipe pequena (2-4 dev), rotação semanal: 1 pessoa de plantão, 1 backup. Alerta vai para PagerDuty/OpsGenie ($10-30/usuário). Critical = liga (qualquer hora), warning = notifica em horário comercial. Documente runbook por tipo de alerta — sem runbook, on-call vira pesquisa no Confluence às 3h da manhã. Faça "game day" trimestral: simule falha em staging durante hora comercial, equipe segue runbook, meça tempo de resolução e pontos de fricção. Prática em ambiente controlado evita pânico em ambiente real.

Nunca mais fique cego em produção. A ZAP API expõe endpoints prontos de health, diagnostics e summary com X-Diagnostic-Token. Prometheus exporter, dashboards Grafana e webhooks pra Slack — tudo documentado. Criar conta grátis e plugue seu stack.

Experimente a ZAP API gratuitamente

7 dias de trial sem precisar de cartão. A partir de R$29/mês*.

Criar instância grátis
EE
Equipe Editorial ZAP APIRevisão técnica

Desenvolvedores e especialistas em integrações WhatsApp. Todo conteúdo passa por revisão técnica para garantir precisão e aplicabilidade.

Ver perfil completoDocumentaçãoTrial grátis

Leia também

Observabilidade · 21 de mai. de 2026 · 12 min

Endpoint de diagnóstico: monitorar instâncias WhatsApp sem SSH

Use o endpoint de diagnóstico da ZAP API para consultar métricas de saúde, alertas e performance de instâncias WhatsApp via HTTP, sem precisar de acesso SSH ao servidor.

Observabilidade · 08 de mai. de 2026 · 12 min

Health score de sessão WhatsApp: monitorar e agir antes de cair

Como usar o Session Quality Score da ZAP API para detectar instâncias degradadas antes que caiam, com alertas automáticos e ação corretiva via código.

Arquitetura · 26 de mai. de 2026 · 14 min

Multi-instância WhatsApp: arquitetura para escalar sem banimento

Como distribuir envios entre múltiplas instâncias WhatsApp para escalar volume, isolar clientes e proteger números críticos de banimento por sobrecarga.

Arquitetura · 15 de mai. de 2026 · 13 min

Circuit breaker em WhatsApp API: proteja sua instância de sobrecarga

Implemente circuit breaker para sua integração WhatsApp: evite cascata de falhas, proteja sua instância de rate limiting e garanta degradação graciosa.

Tópicos:Chatbots com IAE-commerceAPI WhatsApp

Explore também

Casos de usoWhatsApp API por segmentoComparativoZAP API vs alternativasPreçosPlanos e o que está inclusoGlossárioTermos técnicos de WhatsApp API
ZAP-API

API REST para WhatsApp com webhooks assinados, Meta Pixel/CAPI e compliance LGPD. Sem aprovação da Meta.

Status operacional🇧🇷 Feito no Brasil

Produto

  • Preços
  • Casos de uso
  • Comparativo
  • Trial grátis
  • Dashboard

Recursos

  • Documentação
  • Blog
  • Glossário
  • RSS Feed

Empresa

  • Sobre
  • Imprensa
  • Termos de uso
  • Privacidade
  • Criar conta
  • Login

Contato

  • [email protected]
  • [email protected]
  • Resposta em até 24h úteis
© 2026 ZAP-API — Todos os direitos reservados·CNPJ 42.130.949/0001-56·Termos·Privacidade

Desenvolvido por PreviusIA