← Blog/Atualizado em 16 de outubro de 2026·15 min de leitura

Observabilidade na prática: do sistema interno ao SaaS

Logs, métricas e traces sem enrolação. Ferramentas gratuitas, pagas e self-hosted, quanto custam, como escalar e o que monitorar em SaaS, ERP e sistemas internos.

Todo sistema em produção tem um dia ruim. A diferença está em quem descobre primeiro: você ou quem usa. Num SaaS, o cliente abre um chamado. Num ERP, a nota fiscal não sai e o fechamento do mês trava. Num sistema interno, ninguém reclama: as pessoas só voltam para a planilha.

Observabilidade é a capacidade de responder "o que está acontecendo e por quê?" olhando para os dados que o sistema já emite, sem precisar subir um deploy novo cheio de console.log.

Este post junta os conceitos, o que medir primeiro, as ferramentas (gratuitas, pagas e self-hosted), quanto custam e como a arquitetura muda quando o sistema cresce. No fim tem um checklist para aplicar em qualquer projeto.

Monitoramento ou observabilidade?

Monitoramento responde perguntas que você já conhecia: "a CPU passou de 90%?", "o site está no ar?".

Observabilidade responde perguntas que você não previu: "por que só os clientes do plano Enterprise estão com o relatório lento desde terça?".

Os dois se completam. O monitoramento avisa que algo quebrou; a observabilidade ajuda a descobrir o quê.

Os sinais

SinalO que éRespondeExemplo
LogsRegistros de eventos, com contextoO que aconteceu, em detalhe?pedido 4821 falhou: timeout no gateway
MétricasNúmeros agregados ao longo do tempoQuanto? Está piorando?Requisições por segundo, latência p95, tamanho da fila
TracesO caminho de uma requisição por todos os serviçosOnde o tempo foi gasto?API → banco (40 ms) → serviço fiscal (2,1 s)
ProfilesOnde o código gasta CPU e memóriaQual função pesa?60% da CPU no parser de XML
RUMDados do navegador de quem usaComo está para o usuário real?LCP, erros de JavaScript, cliques sem resposta

Regra prática: métricas avisam, traces localizam, logs explicam.

O que medir primeiro

Não comece instrumentando tudo. Comece pelo que diz se o usuário está sendo atendido.

RED, para tudo que recebe requisição

  • Rate: requisições por segundo.
  • Errors: porcentagem que falha.
  • Duration: latência em percentis (p50, p95, p99). Média esconde o problema: se 5% das requisições levam 8 segundos, a média ainda parece ótima.

USE, para recursos

Utilization, Saturation e Errors de CPU, memória, disco, conexões do banco e filas. Saturação costuma ser o mais revelador: uma fila que só cresce ou um pool de conexões sempre cheio avisam antes da CPU.

Métricas de negócio

Muitas vezes são as mais úteis: notas emitidas por hora, pedidos finalizados, boletos gerados, logins. Se a emissão de notas cai a zero numa terça às 10h, algo quebrou, mesmo com a CPU tranquila e nenhum erro registrado.

SLOs: quanto erro é aceitável

Um SLI é o que você mede (por exemplo, % de requisições com sucesso em menos de 500 ms). Um SLO é a meta (99,5% em 30 dias). A diferença, 0,5%, é o error budget: quanto de falha dá para gastar antes de pausar features e cuidar da estabilidade.

SLOIndisponibilidade permitida por mês
99%~7 h 18 min
99,5%~3 h 39 min
99,9%~44 min
99,99%~4 min

Cada 9 a mais custa bem mais caro. Um sistema interno usado em horário comercial raramente precisa de 99,9%.

OpenTelemetry: instrumente uma vez

OpenTelemetry (OTel) é o padrão aberto da CNCF para gerar e enviar logs, métricas e traces. Quase todas as ferramentas deste post aceitam OTel: você instrumenta o código uma vez e troca de fornecedor mudando uma configuração, não o código.

Este é o conselho mais importante do post: não amarre o código ao SDK proprietário de um fornecedor. Preço muda, a empresa cresce, e trocar de ferramenta não deveria exigir reescrever a instrumentação.

No Next.js, o framework já vem instrumentado. Basta um instrumentation.ts na raiz do projeto (ou dentro de src):

TypeScript
import { registerOTel } from "@vercel/otel";

export function register() {
  registerOTel({ serviceName: "erp-api" });
}

Para medir uma operação específica, crie um span:

TypeScript
import { SpanStatusCode, trace } from "@opentelemetry/api";

const tracer = trace.getTracer("faturamento");

export async function emitirNota(pedidoId: string) {
  return tracer.startActiveSpan("emitir-nota", async (span) => {
    span.setAttribute("pedido.id", pedidoId);
    try {
      return await enviarParaSefaz(pedidoId);
    } catch (err) {
      span.recordException(err as Error);
      span.setStatus({ code: SpanStatusCode.ERROR });
      throw err;
    } finally {
      span.end();
    }
  });
}

O destino dos dados vem de variáveis de ambiente padrão, como OTEL_EXPORTER_OTLP_ENDPOINT, e não do código. Java, .NET, Python, Go e PHP têm SDKs equivalentes, e vários oferecem instrumentação automática, sem mexer no código.

Logs que ajudam de verdade

  • Estruturados (JSON), não texto solto. Assim dá para filtrar por campo:

    Texto
    tenant_id = 42 AND level = error
  • Com trace_id. É o que liga o log ao trace: do erro você chega à requisição inteira, e vice-versa.

  • Níveis com critério: error é algo que alguém precisa olhar; warn é algo estranho que se resolveu sozinho; info são eventos de negócio; debug fica desligado em produção.

  • Sem dados pessoais. CPF, e-mail, token, senha e dados de cartão não vão para o log. Pela LGPD, log também é tratamento de dado pessoal, e ele costuma parar em lugares com menos controle de acesso que o banco.

JSON
{
  "time": "2026-10-16T13:04:22.118Z",
  "level": "error",
  "service": "erp-api",
  "tenant_id": "42",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "msg": "falha ao emitir nota",
  "pedido_id": "4821",
  "erro": "timeout após 30s",
  "tentativa": 3
}

As ferramentas

Open source e self-hosted

Grátis na licença, não na operação: você paga em servidor, disco e horas de alguém cuidando.

FerramentaPara quêObservação
PrometheusMétricasO padrão de fato. Coleta por pull, consultas em PromQL, alertas com Alertmanager
GrafanaDashboards e alertasLê de quase tudo: Prometheus, Loki, Postgres, Elasticsearch, CloudWatch
LokiLogsIndexa só os labels, não o texto. Barato de manter, guarda em object storage (S3)
TempoTracesTambém em object storage; no Grafana, liga trace, log e métrica
Mimir / VictoriaMetricsMétricas em escalaQuando um Prometheus sozinho não aguenta: retenção longa, alta disponibilidade, multi-tenant
JaegerTracesProjeto da CNCF, simples para começar
SigNozTudo em umLogs, métricas e traces sobre ClickHouse, nativo de OTel
Elastic / OpenSearchLogs e buscaExcelente para busca em texto; pesado em memória e disco
Sentry / GlitchTipErrosStack trace, usuário afetado e release. O Sentry self-hosted é pesado; o GlitchTip é leve e aceita o SDK do Sentry
Uptime KumaUptimeCheca HTTP, TCP e DNS e alerta no Telegram, Slack ou e-mail. Sobe num container
NetdataServidoresMétricas de máquina em tempo real, quase sem configuração
OTel CollectorPipelineRecebe, filtra, amostra e encaminha a telemetria para um ou mais destinos

A combinação mais comum, e que cobre bem a maioria dos casos, é OTel Collector + Prometheus + Loki + Tempo + Grafana. Dá para começar num único servidor com Docker Compose, e para testar localmente existe a imagem grafana/otel-lgtm, com tudo junto num container só.

Planos gratuitos de SaaS

Para começar sem servidor nenhum. Valores de outubro de 2026; confira a página oficial, porque mudam com frequência.

ServiçoO que o plano grátis inclui
Grafana Cloud10 mil séries de métricas ativas, 50 GB de logs, 50 GB de traces, 14 dias de retenção
New Relic100 GB de dados por mês e 1 usuário com acesso completo
Sentry5 mil erros por mês, 1 usuário
Honeycomb20 milhões de eventos por mês (cada span conta como um evento)
Better StackMonitores de uptime, status page e um volume pequeno de logs

Para um sistema interno ou um SaaS no começo, Sentry (erros) + Grafana Cloud (métricas, logs e traces) + um monitor de uptime costuma caber no plano grátis por um bom tempo.

Plataformas pagas

PlataformaComo cobraPonto forte
DatadogPor host, por GB e por métrica customizadaTudo integrado, centenas de integrações prontas
New RelicPor GB ingerido e por usuárioPrevisível para times pequenos com muito dado
DynatracePor host/memória e por consumoDescoberta automática e análise de causa raiz; forte em grandes empresas
HoneycombPor eventoInvestigar com alta cardinalidade: filtrar por qualquer campo, até id de cliente
Grafana CloudPor série, por GB e por usuárioO stack open source gerenciado, sem lock-in
Elastic CloudPor recursos (memória e armazenamento)Busca em logs
Amazon CloudWatch, Azure Monitor, Google Cloud ObservabilityPor GB, por métrica e por consultaJá vem integrado quando toda a infraestrutura está naquela nuvem

Para ter uma ordem de grandeza, o Datadog em preço de lista anual: cerca de US$ 15 por host/mês para infraestrutura e US$ 31 por host/mês para APM. Logs são cobrados duas vezes: US$ 0,10 por GB ingerido e mais um valor por milhão de eventos indexados. Dez servidores com APM já passam de US$ 450 por mês antes de qualquer log.

As armadilhas de custo

A conta de observabilidade quase nunca explode pelo plano. Explode pelo volume.

  • Cardinalidade. Cada combinação única de labels vira uma série. Uma métrica http_requests com rota (50) × status (5) × metodo (4) são 1.000 séries. Acrescente user_id com 20 mil usuários e são 20 milhões. Nunca use id de usuário, pedido ou requisição como label de métrica; isso vai em traces e logs.
  • Debug em produção. Um log.debug dentro de um loop pode gerar mais GB que o resto do sistema inteiro.
  • Retenção. Guardar tudo por um ano raramente faz sentido. Erros e traces: 15 a 30 dias. Métricas agregadas: meses. Logs de auditoria: o que a lei ou o contrato exigir, em armazenamento barato.
  • Health checks. O load balancer bate no /health a cada poucos segundos, e cada batida vira log e trace. Filtre antes de pagar por eles.
  • Cobrança por host com autoscaling. Com Kubernetes ou autoscaling, o número de hosts varia, e alguns fornecedores cobram pelo pico do mês.

Self-hosted ou SaaS?

CritérioSelf-hostedSaaS
Custo para começarBaixo (um servidor)Zero no plano grátis
Custo em escalaMenor por GB, mas inclui genteCresce com o volume, às vezes rápido
OperaçãoUpgrade, disco, backup e alta disponibilidade são seusProblema do fornecedor
Dados sensíveis e LGPDFicam na sua infraestruturaAvaliar contrato, região e o que é enviado
Tempo até o primeiro dashboardHoras a diasMinutos
Quem monitora o monitoramento?VocêO fornecedor

A regra que eu sigo: comece em SaaS, com OpenTelemetry no código. Considere self-hosted quando a conta passar do custo de um servidor mais algumas horas de manutenção por mês, ou quando houver exigência de que os dados não saiam da sua infraestrutura. Como o código fala OTel, migrar é trocar o destino no Collector.

Uma pegadinha do self-hosted: se o servidor de monitoramento cai junto com o sistema, você fica cego justo quando mais precisa. Mantenha pelo menos um monitor de uptime fora da sua infraestrutura.

Como escalar

A observabilidade cresce em fases, junto com o sistema.

Fase 1: um app, um banco

  • Erros com stack trace (Sentry ou GlitchTip).
  • Monitor de uptime externo nos endpoints principais.
  • Logs estruturados, centralizados num lugar só.
  • Um painel com RED da API e as principais métricas de negócio.
  • Alertas para: sistema fora do ar, taxa de erro alta, fila parada.

Isso já resolve a maior parte dos incidentes de um sistema interno ou de um SaaS pequeno.

Fase 2: alguns serviços, filas e integrações

  • Traces distribuídos com OTel, para seguir uma requisição da API até o worker e a integração externa.
  • trace_id em todos os logs.
  • SLOs para os fluxos críticos: login, checkout, emissão de nota.
  • Um OTel Collector entre os apps e o destino, para filtrar e rotear sem mexer nos apps.

Fase 3: muitos serviços, muitos times, muito volume

  • Collector em duas camadas: um agente em cada máquina ou nó (coleta local, pouco processamento) e um gateway central (amostragem, filtros, roteamento).
  • Amostragem de traces. Guardar 100% dos traces de um sistema com milhões de requisições é caro e quase inútil. Há dois jeitos:
    • Head sampling: decide no início da requisição (guarda 10%, por exemplo). Simples e barato, mas pode descartar justo o trace do erro.
    • Tail sampling: decide no fim, depois de ver o trace inteiro. Guarda todos os erros e requisições lentas e só uma amostra do resto. Exige um gateway que segure os spans na memória por alguns segundos.
  • Métricas derivadas de traces: o Collector calcula RED a partir dos spans antes de amostrar, então as métricas continuam exatas mesmo guardando 5% dos traces.
  • Armazenamento em camadas: dados recentes em disco rápido, antigos em object storage (S3, R2, GCS). Loki, Tempo e Mimir já funcionam assim.
  • Métricas em escala: Prometheus sozinho vai até certo ponto; depois entram Mimir, VictoriaMetrics ou Thanos, para alta disponibilidade e retenção longa.
  • Governança: nomes padronizados (as semantic conventions do OTel), limite de cardinalidade por time e um dono para cada dashboard e alerta.

Um gateway com filtro de health check e tail sampling fica assim (processadores da distribuição contrib do Collector):

YAML
receivers:
  otlp:
    protocols:
      grpc:
      http:

processors:
  # Descarta health checks antes de pagar por eles
  filter/health:
    error_mode: ignore
    traces:
      span:
        - 'attributes["url.path"] == "/health"'
  # Guarda todos os erros, tudo acima de 1 s e 10% do resto
  tail_sampling:
    decision_wait: 10s
    policies:
      - name: erros
        type: status_code
        status_code: { status_codes: [ERROR] }
      - name: lentos
        type: latency
        latency: { threshold_ms: 1000 }
      - name: amostra
        type: probabilistic
        probabilistic: { sampling_percentage: 10 }
  batch:

exporters:
  otlphttp:
    endpoint: https://otlp.exemplo.com.br

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [filter/health, tail_sampling, batch]
      exporters: [otlphttp]

Com mais de uma instância do gateway, todos os spans de um mesmo trace precisam cair na mesma instância. Para isso, a camada de agentes usa o exporter loadbalancing, que distribui por trace_id.

Alertas que não viram ruído

  • Alerte no sintoma, não na causa. "Taxa de erro do checkout acima de 2% por 5 minutos" é acionável. "CPU em 85%" muitas vezes não é: se o usuário está bem, ninguém precisa acordar.
  • Alerte pelo consumo do error budget (burn rate): avisa quando, no ritmo atual, o SLO do mês vai estourar. Pega tanto quedas bruscas quanto degradação lenta.
  • Todo alerta tem dono e runbook: o que olhar primeiro, como mitigar, quem chamar.
  • Dois níveis: o que acorda alguém (sistema fora, dinheiro parado) e o que vira tarefa para o dia seguinte.
  • Revise todo mês. Alerta que dispara e ninguém age deve ser ajustado ou apagado.

Ferramentas de plantão como o PagerDuty, ou a gestão de incidentes do Grafana e do Better Stack, organizam escala e escalonamento. Para times pequenos, um canal no Slack ou no Telegram bem filtrado resolve.

Por tipo de sistema

SaaS

  • tenant_id em todo log e trace. A pergunta mais comum do suporte é "o que aconteceu com o cliente X?".
  • SLO por plano ou por cliente grande. A média do sistema pode estar ótima enquanto um cliente está péssimo.
  • Vizinho barulhento: um tenant que importa 1 milhão de linhas pode degradar todo mundo. Métricas de uso por tenant mostram isso (com cuidado de cardinalidade se forem milhares de tenants).
  • Erros de front-end e RUM: boa parte do que o cliente sente acontece no navegador, não na API.
  • Status page pública: reduz chamados durante um incidente.

ERP

  • Jobs agendados são o coração: fechamento, conciliação, folha, importação de extrato. O erro mais perigoso é o job que não roda: não gera erro nem log. Use um heartbeat (dead man's switch): o job avisa quando termina, e o alerta dispara se o aviso não chegar. O Healthchecks.io e o Uptime Kuma (monitor do tipo push) fazem isso.
  • Integrações externas: SEFAZ, bancos, gateways de pagamento e transportadoras caem e ficam lentos. Meça latência e erro por integração, com timeouts e retries visíveis.
  • Filas: tamanho da fila, idade da mensagem mais antiga e o que caiu na dead letter queue.
  • Picos previsíveis: fim de mês, fechamento fiscal, folha. Compare com o mesmo período do mês anterior, não com a semana passada.
  • Banco de dados: consultas lentas (pg_stat_statements no Postgres, Query Store no SQL Server), locks e conexões. Em ERP, o gargalo quase sempre está no banco.
  • Auditoria não é observabilidade. Quem alterou o quê fica no banco, com retenção e controle próprios, não num log que expira em 15 dias.

Sistemas internos

  • Orçamento pequeno, impacto grande: se o sistema de pedidos para, a operação para.
  • O mínimo resolve: erros, uptime e logs centralizados. Cabe num plano gratuito ou num servidor pequeno.
  • Uso é um sinal: se o número de usuários ativos cai, pode ser bug, lentidão ou um processo que mudou. Ninguém vai abrir chamado.
  • Horário comercial: fora do expediente, só alerta o que realmente para a empresa.

Uma stack por tamanho

CenárioSugestão
Sistema interno, um devSentry ou GlitchTip + Uptime Kuma + logs em JSON
SaaS no começoOTel + Sentry + Grafana Cloud (plano grátis) + status page
SaaS ou ERP crescendo, sem time de infraOTel + uma plataforma paga (Datadog, New Relic, Honeycomb ou Grafana Cloud)
Volume alto ou dados que não podem sairOTel Collector + Prometheus/Mimir + Loki + Tempo + Grafana, self-hosted
Muitos times, orçamento grandePlataforma paga com contrato negociado, ou self-hosted com time dedicado

Em todas as linhas, o OpenTelemetry é a constante: é ele que permite mudar de linha nesta tabela sem reescrever nada.

Checklist

  • Erros capturados com stack trace e versão do deploy
  • Monitor de uptime externo, fora da sua infraestrutura
  • Logs em JSON, centralizados, com trace_id e sem dados pessoais
  • RED (taxa, erros, latência p95/p99) nos endpoints principais
  • Pelo menos uma métrica de negócio por fluxo crítico
  • Heartbeat em todo job agendado
  • Latência e erro por integração externa
  • Instrumentação com OpenTelemetry, sem SDK proprietário no código
  • Nenhum id de usuário ou pedido como label de métrica
  • Retenção definida por tipo de dado
  • Health checks filtrados
  • SLO para os fluxos críticos
  • Alertas no sintoma, com dono e runbook
  • Revisão mensal de alertas e custos
--fps