Monitoring stack completa em 2026: Prometheus + Grafana + Loki passo a passo

Tutorial honesto pra subir métricas, logs e dashboards pro seu cluster — em 4 horas, sem Datadog. Stack open-source que cabe em 1 VPS de R$80/mês.

Equipe HeroCtl··16 min

A primeira vez que o seu site cair às três da manhã, você vai descobrir uma coisa desconfortável: não tem como saber o que aconteceu. Não tem gráfico de CPU, não tem log do contêiner que morreu, não tem alerta que avisou antes. Você vai abrir um terminal, conectar nos servidores um por um, rodar top, df, journalctl, e tentar reconstituir uma cena de crime que já esfriou.

Esse post é o atalho pra você não passar por isso. Em quatro horas, com R$80 a R$120 por mês de hardware, dá pra montar a stack de observabilidade open-source que substitui Datadog, New Relic e CloudWatch em 95% dos casos pra startup. As ferramentas são as mesmas que rodam dentro de empresas com dezenas de milhares de servidores — e cabem confortavelmente num VPS pequeno pro time que está começando.

TL;DR

A stack de monitoring open-source padrão em 2026 — Prometheus + Grafana + Loki + Alertmanager — cabe em um único VPS de 4 GB de RAM e cobre métricas, logs centralizados, dashboards e alertas. Esse tutorial mostra setup passo a passo pra um cluster de 4 a 5 servidores em aproximadamente quatro horas, usando docker-compose ou job specs do orquestrador.

Pra startup brasileira, isso significa R$80 a R$120 por mês de hardware contra R$1.000 a R$2.000 por mês de SaaS de observabilidade equivalente. O custo de tempo é honesto: quatro horas de setup inicial mais duas a quatro horas por mês de manutenção contínua.

Resultado entregável ao final do tutorial: dashboards de CPU, RAM, disco, rede e métricas HTTP; logs pesquisáveis com retenção de 30 dias; alertas roteados pra Slack, Discord ou e-mail. Pré-requisitos: 1 VPS Linux com 4 GB de RAM e 50 GB de SSD, Docker instalado, e um domínio com DNS controlado por você.

A escolha entre rodar essa stack num VPS dedicado fora do cluster de produção ou como job dentro do próprio orquestrador é uma decisão arquitetural — cobrimos as duas opções no passo 8 e em "Como rodar isso dentro do HeroCtl".

O que cada componente faz, em uma frase

Antes de instalar qualquer coisa, vale entender o papel de cada peça. A stack tem seis componentes; a confusão geralmente vem de pensar que algum deles é "o sistema de monitoring". Não é. Cada um faz uma coisa.

  • Prometheus é um banco de dados de séries temporais (TSDB) que coleta métricas via HTTP scrape — ele puxa os números, ninguém empurra. Retém 15 dias por padrão.
  • Grafana é a camada de visualização. Conecta em Prometheus, em Loki, em Postgres, em quase qualquer fonte estruturada, e desenha gráficos.
  • Loki é a peça de logs. Sintaxe similar ao Prometheus, indexa apenas labels (não o conteúdo dos logs), e por causa disso fica cerca de dez vezes mais barato que ELK pra rodar.
  • Promtail (ou o Grafana Agent, que está substituindo o Promtail em 2026) é o coletor que lê os arquivos de log de cada servidor e envia pro Loki.
  • node_exporter roda em cada nó monitorado e expõe um endpoint HTTP com CPU, RAM, disco e rede em formato Prometheus.
  • Alertmanager recebe regras de alerta do Prometheus e cuida do roteamento — Slack, e-mail, PagerDuty, webhook arbitrário.

Quem desenha a primeira stack costuma confundir Prometheus com "monitoring" e Grafana com "dashboards bonitos". A separação real é: Prometheus guarda números, Loki guarda texto, Grafana mostra ambos, Alertmanager grita quando algum número fica errado.

Qual é a arquitetura recomendada?

Pra um cluster de 3 a 5 servidores rodando aplicações de produção, a topologia que tem dado certo na prática é separar o servidor de observabilidade do resto. Um nó dedicado, fora do cluster que ele monitora, com dois objetivos: não morrer junto quando o cluster morrer, e não competir por CPU/RAM com a aplicação real.

  • 1 servidor "observability" dedicado, 4 GB de RAM, 50 GB de SSD. Roda Prometheus, Grafana, Loki, Alertmanager.
  • Cada servidor monitorado roda apenas dois processos leves: node_exporter (métricas de sistema) e Promtail (envio de logs).
  • As suas aplicações expõem um endpoint /metrics em formato Prometheus. Se você usa um framework popular, existe um cliente pronto. Se não, é uma biblioteca de poucas dezenas de linhas.
  • Grafana fica acessível via subdomínio (monitor.seudominio.com) com TLS automático e autenticação básica em frente.

Essa separação tem um custo: você paga por mais um VPS. Em troca, quando o cluster principal cair, você ainda consegue olhar os gráficos pra entender o que aconteceu. Pra startup, esse trade-off compensa quase sempre — o pior cenário em monitoring é descobrir que a única coisa que parou junto com o site foi o sistema que ia te avisar que o site parou.

Passo 1 — Como provisionar o VPS de observabilidade?

Tempo estimado: 10 minutos.

Qualquer provedor barato serve. Os dois com melhor custo-benefício pro caso brasileiro hoje são a Hetzner (CPX21 a 7,99 EUR por mês com 3 vCPUs e 4 GB de RAM, datacenter na Alemanha) e a DigitalOcean (Basic Droplet de US$24 por mês com a mesma configuração, datacenters mais próximos do Brasil). Pra workload de monitoring, latência de scrape em datacenter europeu não causa problema — Prometheus puxa a cada 15 segundos por padrão, então 200ms de RTT entre Hetzner e seus servidores não atrapalha.

Provisionando:

  1. Crie o VPS com Ubuntu 24.04 LTS ou Debian 12.
  2. Adicione a sua chave SSH pública na criação. Desabilite login por senha.
  3. Instale Docker e o plugin de compose: curl -fsSL https://get.docker.com | sh && apt install docker-compose-plugin.
  4. Configure o firewall: porta 22 (SSH) aberta, porta 443 (HTTPS) aberta, todas as outras fechadas. As portas internas (3000, 9090, 3100, 9093) só ficam acessíveis pelo localhost do próprio VPS — o reverse proxy expõe Grafana via 443.
  5. Aponte o DNS: crie um registro A monitor.seudominio.com pra o IP do VPS.

Validação: docker --version retorna 26.x ou superior; dig monitor.seudominio.com retorna o IP correto; ssh root@monitor.seudominio.com conecta sem pedir senha.

Passo 2 — Como subir a stack via docker-compose?

Tempo estimado: 45 minutos.

Crie o diretório de trabalho em /opt/observability/ com a seguinte estrutura:

/opt/observability/
├── docker-compose.yml
├── prometheus/
│   ├── prometheus.yml
│   └── alerts.yml
├── alertmanager/
│   └── alertmanager.yml
├── loki/
│   └── loki-config.yml
└── grafana/
    └── provisioning/
        └── datasources/
            └── datasources.yml

O docker-compose.yml abreviado mas funcional:

services:
  prometheus:
    image: prom/prometheus:v2.55.0
    volumes:
      - ./prometheus:/etc/prometheus
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.retention.time=30d'
      - '--web.enable-lifecycle'  # permite reload via HTTP POST
    ports:
      - '127.0.0.1:9090:9090'
    restart: unless-stopped

  grafana:
    image: grafana/grafana:11.3.0
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
      - GF_USERS_ALLOW_SIGN_UP=false
    ports:
      - '127.0.0.1:3000:3000'
    restart: unless-stopped

  loki:
    image: grafana/loki:3.2.0
    volumes:
      - ./loki/loki-config.yml:/etc/loki/config.yml
      - loki-data:/loki
    command: -config.file=/etc/loki/config.yml
    ports:
      - '127.0.0.1:3100:3100'
    restart: unless-stopped

  alertmanager:
    image: prom/alertmanager:v0.27.0
    volumes:
      - ./alertmanager:/etc/alertmanager
    ports:
      - '127.0.0.1:9093:9093'
    restart: unless-stopped

volumes:
  prometheus-data:
  grafana-data:
  loki-data:

Três pontos importantes nesse arquivo. Primeiro, todas as portas estão amarradas a 127.0.0.1 — nenhum dos serviços é acessível diretamente da internet. Segundo, os volumes são nomeados (não bind mounts), então sobrevivem a docker-compose down. Terceiro, a senha do Grafana vem de variável de ambiente: crie um .env ao lado do compose com GRAFANA_PASSWORD=algo_longo_aleatorio e nunca comite isso.

Suba a stack:

cd /opt/observability
docker compose up -d
docker compose ps  # todos devem estar "Up" / healthy

Validação rápida: curl localhost:9090/-/ready retorna Prometheus Server is Ready; curl localhost:3100/ready retorna ready; curl localhost:3000/api/health retorna JSON com "database": "ok".

Passo 3 — Como configurar os scrapes do Prometheus?

Tempo estimado: 30 minutos.

O prometheus/prometheus.yml é onde você diz pro Prometheus quais endpoints raspar. Pra um cluster de 4 servidores, fica assim:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

rule_files:
  - 'alerts.yml'

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    static_configs:
      - targets:
          - 'server-1.seudominio.internal:9100'
          - 'server-2.seudominio.internal:9100'
          - 'server-3.seudominio.internal:9100'
          - 'worker-1.seudominio.internal:9100'
        labels:
          environment: 'production'

  - job_name: 'apps'
    static_configs:
      - targets:
          - 'api.seudominio.internal:8080'
          - 'worker.seudominio.internal:8080'
        labels:
          environment: 'production'
    metrics_path: '/metrics'

Pra clusters maiores ou que mudam de composição com frequência, troque o static_configs por file_sd_configs apontando pra um JSON que você gera automaticamente. Pra 4 servidores estáticos, o arquivo acima resolve.

Reload: curl -X POST localhost:9090/-/reload. Confira em localhost:9090/targets se todos os jobs estão UP. Os que estiverem DOWN ainda não foram instrumentados — esse é o passo 4.

Passo 4 — Como instalar o node_exporter em cada servidor?

Tempo estimado: 15 minutos para 4 servidores.

Em cada servidor monitorado, rode o node_exporter. Há duas formas: binário direto via systemd, ou contêiner Docker. Em 2026 o consenso é container — facilita atualização e isolamento. Em cada nó:

docker run -d \
  --name node-exporter \
  --restart unless-stopped \
  --net="host" \
  --pid="host" \
  -v "/:/host:ro,rslave" \
  prom/node-exporter:v1.8.2 \
  --path.rootfs=/host

O --net=host é necessário pra ele enxergar as interfaces de rede reais. O bind mount em /host permite ler /proc, /sys e /etc/passwd do host (read-only) sem rodar o contêiner com privilégios de raiz.

Firewall: abra a porta 9100 apenas pra o IP do servidor de observabilidade. No Ubuntu com ufw:

ufw allow from <IP_DO_OBSERVABILITY> to any port 9100

Validação: do servidor de observability, curl http://server-1.seudominio.internal:9100/metrics deve retornar centenas de linhas começando com # HELP node_cpu_seconds_total....

Passo 5 — Como configurar Loki + Promtail?

Tempo estimado: 30 minutos.

O Loki já está rodando no compose do passo 2. Falta o loki-config.yml:

auth_enabled: false

server:
  http_listen_port: 3100

common:
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

limits_config:
  retention_period: 720h  # 30 dias
  reject_old_samples: true
  reject_old_samples_max_age: 168h

Storage em filesystem é o suficiente pra começar. Quando você passar de 50 GB de logs por dia ou quiser retenção de 90+ dias, migra pra S3 (ou compatível). Não migre antes — complica a operação sem ganho real.

Em cada servidor monitorado, instale o Promtail (ou Grafana Agent) também via container:

# /opt/promtail/promtail-config.yml em cada servidor
server:
  http_listen_port: 9080

clients:
  - url: http://monitor.seudominio.com:3100/loki/api/v1/push

scrape_configs:
  - job_name: system
    static_configs:
      - targets: [localhost]
        labels:
          job: varlogs
          host: ${HOSTNAME}
          __path__: /var/log/*.log

  - job_name: docker
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
    relabel_configs:
      - source_labels: ['__meta_docker_container_name']
        target_label: 'container'

Importante: o endpoint http://monitor.seudominio.com:3100/loki/api/v1/push precisa estar acessível dos servidores. Se você seguiu o passo 2 e amarrou Loki em 127.0.0.1, você tem duas opções: expor a 3100 via reverse proxy com autenticação básica, ou abrir um túnel SSH/WireGuard entre os servidores. A segunda opção é mais segura e o que recomendamos.

Validação: no Grafana, vá em Explore, selecione a fonte de dados Loki, rode {job="varlogs"} e veja os logs aparecendo em tempo real.

Passo 6 — Como importar os dashboards do Grafana?

Tempo estimado: 20 minutos.

Acesse https://monitor.seudominio.com (depois de configurar o reverse proxy do passo 8 — pode pular pra lá agora se quiser). Login admin com a senha do .env.

Adicione as duas fontes de dados via provisioning automático. Em grafana/provisioning/datasources/datasources.yml:

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
  - name: Loki
    type: loki
    access: proxy
    url: http://loki:3100

Reinicie o Grafana com docker compose restart grafana e as fontes aparecem automaticamente.

Importe os dashboards prontos. Em Dashboards → New → Import, cole o ID do dashboard:

  • 1860 — Node Exporter Full. CPU, RAM, disco, rede, sistema de arquivos. É o dashboard mais usado da comunidade Prometheus, com razão.
  • 13639 — Logs / App. Visualização básica de logs do Loki com filtros por job, container, host.
  • 15172 — Cluster overview. Visão consolidada por servidor, útil pra cluster pequeno.

Customize cada um pra usar environment="production" no filtro padrão. Depois de duas semanas usando, você vai querer criar dashboards próprios pra workloads específicos — não tem atalho aí, é tempo de cadeira.

Passo 7 — Como configurar alertas básicos?

Tempo estimado: 45 minutos.

Alertas são onde 80% dos times tropeçam: ou colocam pouquíssimos e descobrem incidentes pelos clientes, ou colocam dezenas e desensibilizam o time.

Comece com seis alertas essenciais. Em prometheus/alerts.yml:

groups:
  - name: essentials
    interval: 30s
    rules:
      - alert: ServerDown
        expr: up{job="node"} == 0
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Servidor {{ $labels.instance }} está fora do ar"

      - alert: HighCPU
        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 10m
        labels:
          severity: warning

      - alert: DiskAlmostFull
        expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 15
        for: 5m
        labels:
          severity: critical

      - alert: HighMemory
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
        for: 10m
        labels:
          severity: warning

      - alert: HighHTTPErrorRate
        expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
        for: 5m
        labels:
          severity: critical

      - alert: HighLatency
        expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 2
        for: 10m
        labels:
          severity: warning

E o alertmanager/alertmanager.yml apontando pra um webhook do Slack ou Discord:

route:
  group_by: ['alertname', 'severity']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'slack-default'
  routes:
    - match:
        severity: critical
      receiver: 'slack-critical'
      repeat_interval: 1h

receivers:
  - name: 'slack-default'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/SEU/WEBHOOK/AQUI'
        channel: '#alerts'
        send_resolved: true

  - name: 'slack-critical'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/SEU/WEBHOOK/AQUI'
        channel: '#alerts-critical'
        send_resolved: true

Dois detalhes que economizam noite de sono. O for: 10m em CPU evita que picos curtos virem alertas — o servidor pode chegar a 95% por 30 segundos e isso ser normal. O repeat_interval: 4h pra warnings garante que um warning resolvido em uma hora não vire 60 mensagens — o Alertmanager agrupa.

Recarregue o Prometheus (curl -X POST localhost:9090/-/reload) e teste forçando um alerta: stress --cpu 4 --timeout 700s em algum servidor deve disparar HighCPU em 10 minutos.

Passo 8 — Como colocar reverse proxy e TLS na frente?

Tempo estimado: 20 minutos.

Pra acessar Grafana via https://monitor.seudominio.com com certificado válido, você precisa de algo na frente da porta 3000. Duas opções:

  1. Roteador integrado do orquestrador — se você já tem o cluster HeroCtl rodando, basta declarar o Grafana como job com ingress: { host: monitor.seudominio.com, tls: true }. Certificado Let's Encrypt automático, sem ferramenta adicional.
  2. Caddy standalone no próprio VPS de observabilidade — também emite Let's Encrypt automaticamente. Caddyfile mínimo:
    monitor.seudominio.com {
      reverse_proxy localhost:3000
      basicauth /login {
        admin <hash_bcrypt>
      }
    }
    

Pra defesa em profundidade, mantenha autenticação básica do Caddy/roteador na frente do login do Grafana — duas barreiras, não uma. A segunda é especialmente importante porque o login default do Grafana é admin/admin e a primeira coisa que bots fazem em um Grafana exposto é tentar essa combinação.

Passo 9 — Como instrumentar métricas de aplicação?

Tempo estimado: varia conforme número de aplicações.

Métricas de sistema são metade da história. A outra metade é o que sua aplicação está fazendo — quantas requisições por segundo, qual a latência p99, quantos erros, qual o tamanho da fila de jobs em background.

Cada linguagem popular tem cliente Prometheus oficial:

  • Node.js: prom-client
  • Python: prometheus-client
  • Ruby: prometheus-client
  • Go: github.com/prometheus/client_golang

O padrão mínimo são três métricas por endpoint HTTP:

  • http_requests_total — counter, com labels method, path, status.
  • http_request_duration_seconds — histogram, mesmo set de labels.
  • app_errors_total — counter, com label kind ("validation", "db", "external_api", etc).

Exponha tudo isso em /metrics. Adicione o endpoint no scrape_configs do Prometheus. Em horas você tem dashboards por endpoint, alertas por taxa de erro, e a capacidade de responder "o que estava acontecendo às 3:14 de ontem" com um gráfico em vez de um chute.

Cuidado com cardinalidade. Cada combinação única de labels vira uma série temporal separada. Se você botar user_id como label, com 100k usuários você cria 100k séries — e o Prometheus vai consumir 8+ GB de RAM só pra indexar isso. Regra prática: labels têm valores em conjuntos pequenos (status code: 5 valores; método: 5 valores; path: dezenas). Identificadores únicos vão em logs, não em métricas.

Como rodar isso dentro do HeroCtl em vez de VPS dedicado?

Pra clusters que já rodam o orquestrador, faz sentido considerar a stack como mais um job. Trade-off: você economiza um VPS, mas perde isolamento (se o cluster morrer, o monitoring morre junto).

A topologia fica assim:

  • 1 job spec único com 4 tasks: prometheus, grafana, loki, alertmanager.
  • Volumes replicados no cluster — os dados sobrevivem a falha de um nó.
  • Roteador integrado faz o TLS automático via subdomínio. Não precisa de Caddy adicional.
  • Métricas do próprio cluster já são expostas em formato Prometheus na API administrativa, então o scrape é direto.

Pra produção crítica, recomendamos a separação física (VPS dedicado fora do cluster). Pra projeto pessoal, MVP, ou time pequeno onde "tudo cair junto" é aceitável, rodar dentro é mais barato e operacionalmente mais simples. O job spec inteiro fica em torno de 80 linhas de manifesto.

Quanto custa essa stack por mês no Brasil?

ItemCusto mensal (BRL)
VPS observability dedicado (4 GB RAM)R$40 a R$80
Object storage pra retenção longa de logs (opcional)R$30
Tempo de manutenção (2 a 4h × valor da hora)R$200 a R$400
Total operacionalR$300 a R$500

Pra comparação, uma assinatura de Datadog ou New Relic com cobertura equivalente (5 hosts, retenção de logs de 30 dias, alertas, dashboards) sai em torno de R$1.500 a R$2.000 por mês — sem contar o overage automático que aparece no fim do mês quando alguém esquece um log verboso ligado.

A diferença não é pequena: em um ano, a stack open-source self-hosted economiza entre R$12.000 e R$18.000. Pra startup em estágio inicial, isso é meio engenheiro júnior.

Tabela de portas, recursos e características por componente

ComponentePortaRAM mínimaDiscoRetenção defaultFormato dos dados
Prometheus9090512 MB10 GB15 diasTSDB binário
Grafana3000256 MB1 GBN/ASQLite ou Postgres
Loki3100512 MB30 GB30 dias (configurável)chunks comprimidos
Promtail / Agent9080128 MBmínimoN/Apassa por valor
Alertmanager9093128 MB1 GBN/Alog de notificações
node_exporter910064 MBmínimoN/Aendpoint de scrape

Essas são as mínimas viáveis pra cluster pequeno. Em produção com 30 servidores e tráfego real, multiplique RAM por 3 e disco por 5.

Os quatro erros que matam stack de monitoring nova

Times montando observabilidade pela primeira vez tropeçam quase sempre nos mesmos quatro erros. Saber sobre eles antes economiza meses.

Não monitorar o monitoring. O Prometheus parou de scrape na quinta-feira; ninguém viu. Na quarta-feira da semana seguinte um servidor caiu de verdade e descobriram que não tinha alerta porque o Prometheus estava morto há 6 dias. Solução: configure um cron externo simples (até um Pingdom gratuito serve) que bate em https://monitor.seudominio.com/api/health a cada 5 minutos e te avisa quando o próprio Grafana cair.

Sem estratégia de retenção. Disco enche em três meses, Prometheus para de gravar, alguém deleta tudo no desespero, perde 90 dias de histórico. Configure --storage.tsdb.retention.time=30d desde o dia um e estabeleça um job de housekeeping.

Cardinalidade alta em labels. Já cobrimos no passo 9, mas vale repetir: cada user_id, request_id ou UUID que vira label é um número que multiplica explosivamente o consumo de RAM do Prometheus. Identificadores únicos vão pra Loki, não pro Prometheus.

Alertas barulhentos. O time recebe 200 alertas por dia. Em duas semanas, ninguém olha mais. Quando o site cair de verdade, o alerta vai estar no meio de outros 199. Solução: comece com seis alertas (os do passo 7), audite a cada duas semanas, e exclua tudo que disparou mas não exigiu ação humana. Alerta sem ação é ruído.

FAQ

Posso rodar tudo num VPS de 2 GB? Tecnicamente sim, pra cluster de até 3 servidores e poucas aplicações. Na prática você vai bater no teto de RAM em 2 a 3 meses, especialmente se importar dashboards densos no Grafana. Pague os 50 reais a mais e vá direto pro VPS de 4 GB — o tempo que você economiza não brigando com OOM kills paga sozinho.

Quanto de disco pra 30 dias de logs? Depende totalmente do volume de logs da sua aplicação. Regra grosseira pra startup pequena: cluster de 4 servidores com aplicações web normais gera 1 a 5 GB de logs por dia depois de compressão do Loki. Trinta dias dá entre 30 e 150 GB. Comece com 50 GB de SSD, monitore o crescimento por duas semanas, expanda se necessário. Se você for muito mais que isso, é hora de ir pra object storage.

Grafana Cloud vs self-hosted, qual escolher? Grafana Cloud free tier é generoso (10k séries, 50 GB de logs, retenção de 14 dias) e elimina o trabalho de manter o servidor. Pra projeto solo ou time muito pequeno, faz sentido. A partir do momento que você passa do free tier, os preços escalam rápido — a partir de US$50/mês — e você perde o controle sobre os dados. Self-hosted custa hardware + tempo, Cloud custa dinheiro + lock-in. Pra empresa que pretende crescer e tem um dev DevOps no time, self-hosted ganha.

Promtail ou Grafana Agent? Em 2026, o Grafana Agent (rebatizado pra Grafana Alloy) está substituindo o Promtail oficialmente. Pra setup novo, vá direto de Alloy. Pra setup que já roda Promtail há tempo, não tem urgência em migrar — o Promtail vai continuar funcionando por anos.

OpenTelemetry encaixa onde nessa stack? OTel é o padrão de instrumentação de aplicação que está consolidando. Em vez de usar prom-client direto, você usa o SDK do OTel e ele exporta pra Prometheus, Loki e Tempo simultaneamente. A vantagem grande é portabilidade — se você quiser trocar Prometheus por outra coisa daqui a 3 anos, sua aplicação não muda uma linha. Pra startup começando hoje, recomendamos OTel desde o dia um.

Como faço backup do Prometheus? Prometheus tem snapshot via API: curl -X POST localhost:9090/api/v1/admin/tsdb/snapshot cria um snapshot no diretório de dados. Faça isso uma vez por dia via cron, faça tar.gz e envie pra object storage. Em caso de desastre, o que você perde é métricas — e métricas, diferente de logs, são tipicamente recuperáveis em horas (volta a coletar e os dashboards voltam). Logs perdidos são perdidos pra sempre, então invista mais em backup de Loki.

Tempo (traces distribuídos) vale instalar agora? Não. Traces ficam úteis a partir do momento que você tem 5+ serviços conversando entre si e debugar latência envolve seguir uma requisição por vários hops. Pra arquitetura monolítica ou poucos serviços, traces dão trabalho desproporcional ao valor. Adicione quando a complexidade pedir.

Loki indexa full-text como ELK? Não, e essa é a feature, não bug. Loki indexa apenas labels (job, host, container, severity) e o conteúdo do log fica comprimido sem índice. Pra buscar texto, você filtra por labels primeiro e depois faz grep nos chunks resultantes. Isso é o que torna o Loki dez vezes mais barato que ELK em RAM e CPU. Em troca, queries de texto livre em todo o histórico são mais lentas. Pra 90% dos casos de debugging, filtrar por job + host + janela de tempo já reduz pra dezenas de MB onde o grep voa.

Próximos passos

Subiu a stack, tem dashboard, tem alerta, tem log pesquisável? Boa. As próximas três coisas que valem o investimento são, em ordem:

  1. Custom dashboards por aplicação — métricas de negócio (assinaturas criadas/hora, jobs processados, fila de e-mails) em vez de só infraestrutura.
  2. Runbooks linkados nos alertas — toda regra em alerts.yml deve ter annotations.runbook_url apontando pra uma página explicando o que fazer. Quando o alerta dispara às 3 da manhã, o sono não pensa.
  3. Revisão mensal de alertas — 30 minutos uma vez por mês auditando o que disparou no mês anterior, deletando o que virou ruído, ajustando thresholds.

Pra quem quer ir além e entender por que escolhemos essa stack em vez de SaaS gerenciado, leia Observabilidade sem Datadog: a stack da startup brasileira. E pra fechar o ciclo de operação — porque não adianta saber que o banco caiu se você não consegue restaurar — vale ler Backup de banco em cluster: estratégias pras 3 da manhã.

Se você quer pular essa montagem toda e rodar a stack como job dentro de um orquestrador que já cuida de TLS, rolling deploy e replicação de volume:

curl -sSL get.heroctl.com/install.sh | sh

Quatro horas viram quarenta minutos. O resto é o mesmo trabalho de pensar quais alertas importam — e nessa parte ninguém te livra.

#prometheus#grafana#loki#monitoring#tutorial#engenharia