Implementando Observabilidade com Prometheus e Grafana: Um Guia Prático
Aprenda a configurar uma stack de observabilidade robusta do zero. Veja como instalar Prometheus e Grafana via Docker Compose, instrumentar aplicações e configurar alertas eficientes.
Imagine a seguinte cena: o sistema de produção começa a apresentar lentidão extrema. Os usuários reclamam, o suporte fica sobrecarregado e a equipe de engenharia começa a debugar o problema às cegas. Alguém abre o terminal para olhar o consumo de CPU, outro tenta ler arquivos de log gigantescos manualmente, enquanto um terceiro reinicia o servidor na esperança de resolver o problema temporariamente.
Esse cenário caótico é a realidade de times que operam sem visibilidade sobre seus sistemas. Resolver incidentes sem dados concretos de telemetria é como tentar pilotar um avião sem painel de instrumentos. É nesse contexto que a dupla Prometheus e Grafana se consolidou como o padrão de mercado para coleta, armazenamento e visualização de métricas em tempo real.
Neste guia prático, você aprenderá a configurar uma stack de observabilidade do zero, entenderá como instrumentar suas aplicações e verá como criar alertas inteligentes para agir antes que seu cliente perceba uma falha.
O que é Observabilidade e por que ela vai além do monitoramento tradicional
Embora frequentemente usados como sinônimos, monitoramento e observabilidade possuem propósitos diferentes. O monitoramento tradicional foca em responder à pergunta: “O sistema está funcionando?”. Ele é baseado em regras estáticas e limites predefinidos (por exemplo, disparar um alerta se o uso de CPU passar de 90% ou se o endpoint /health retornar um erro).
A observabilidade, por outro lado, busca responder: “Por que o sistema está se comportando dessa maneira?”. Ela permite inferir o estado interno de um sistema complexo apenas analisando suas saídas externas. Em arquiteturas modernas de microserviços ou em uma arquitetura orientada a eventos, onde as falhas são silenciosas e distribuídas, a observabilidade é o pilar da estabilidade para evitar surpresas na infraestrutura.
Para alcançar esse nível de visibilidade, baseamos a observabilidade em três pilares fundamentais:
- Métricas: Dados numéricos agregados ao longo do tempo (ex: taxa de requisições por segundo, latência de banco de dados). Excelente para identificar quando e onde há uma anomalia.
- Logs: Registros textuais de eventos discretos que ocorreram em um momento específico. Essencial para entender o contexto detalhado de um erro após ele ter sido localizado pelas métricas.
- Traces (Rastreamento): O caminho de uma requisição trafegando por múltiplos serviços. Crucial para identificar gargalos de latência em sistemas distribuídos.
Entender esses conceitos e aplicar ferramentas adequadas de monitoramento e observabilidade são cruciais em DevOps, pois garantem que o ciclo de entrega contínua seja acompanhado por uma validação em tempo real da saúde da aplicação.
A Stack de Métricas: O papel do Prometheus e do Grafana
Para implementar o pilar de métricas, a combinação de Prometheus e Grafana é imbatível devido à complementaridade de suas funções:
- Prometheus: É um ecossistema de monitoramento de código aberto projetado especificamente para dados de séries temporais (time-series). Ele funciona através de um modelo de pull, o que significa que ele ativamente busca (faz o scrape) as métricas expostas pelas aplicações em endpoints HTTP específicos, em intervalos regulares. Ele armazena esses dados localmente e oferece uma linguagem de consulta poderosa chamada PromQL (Prometheus Query Language).
- Grafana: É a camada de visualização. Ele se conecta ao Prometheus (e a dezenas de outras fontes de dados) para construir dashboards interativos, dinâmicos e altamente personalizáveis.
Em uma arquitetura de observabilidade mais ampla, essa stack pode ser expandida. O Grafana pode centralizar não apenas métricas do Prometheus, mas também logs consolidados via Grafana Loki e traces distribuídos via Jaeger ou Grafana Tempo, oferecendo uma experiência unificada de correlação de dados.
Configurando o Ambiente: Docker Compose com Prometheus e Grafana
A forma mais rápida e eficiente de subir essa stack em um ambiente de desenvolvimento é utilizando o Docker para facilitar o desenvolvimento. A conteinerização garante que o ambiente local seja idêntico ao que será promovido para homologação ou produção.
Se você ainda está se familiarizando com esses conceitos, vale a pena ler sobre o que são Containers e Orquestração para entender a base dessa tecnologia.
Crie um diretório para o seu projeto e salve o seguinte arquivo docker-compose.yml:
version: '3.8'
services:
prometheus:
image: prom/prometheus:v2.45.0
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
networks:
- monitoring
grafana:
image: grafana/grafana:10.0.0
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
networks:
- monitoring
networks:
monitoring:
driver: bridge
Agora, no mesmo diretório, crie o arquivo de configuração básica do Prometheus, o prometheus.yml:
global:
scrape_interval: 15s # Intervalo padrão de coleta de métricas
evaluation_interval: 15s # Intervalo para avaliar regras de alerta
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
Para iniciar os serviços, execute o comando no terminal:
docker compose up -d
Após o download e inicialização das imagens, você terá:
- O painel do Prometheus acessível em
http://localhost:9090 - O painel do Grafana acessível em
http://localhost:3000(usuárioadmine senhaadminconforme configurado nas variáveis de ambiente).
Coleta de Métricas na Prática: Configurando o Prometheus e Exporters
O Prometheus não invade sua aplicação para ler dados. Ele espera que a aplicação exponha suas métricas em um formato de texto plano específico através de uma rota HTTP (geralmente /metrics).
Existem duas formas de fazer isso:
- Exporters: Agentes externos que coletam métricas de sistemas que não expõem o formato do Prometheus nativamente (ex: bancos de dados como PostgreSQL ou MySQL, servidores Nginx, ou métricas do próprio sistema operacional com o Node Exporter).
- Instrumentação Direta: Bibliotecas adicionadas ao código da sua aplicação para expor métricas customizadas de negócio ou de runtime.
Exemplo 1: Instrumentação em Node.js
Se você desenvolve em JavaScript/TypeScript, pode utilizar a biblioteca oficial prom-client para expor métricas padrão do runtime do Node.js e criar métricas personalizadas.
const express = require('express');
const client = require('prom-client');
const app = express();
const port = 3000;
// Habilita a coleta de métricas padrão do Node.js (CPU, memória, event loop)
const collectDefaultMetrics = client.collectDefaultMetrics;
collectDefaultMetrics({ register: client.register });
// Cria uma métrica personalizada: Contador de requisições HTTP
const httpRequestCounter = new client.Counter({
name: 'http_requests_total',
help: 'Total de requisições HTTP recebidas',
labelNames: ['method', 'route', 'status']
});
// Middleware para registrar as requisições
app.use((req, res, next) => {
res.on('finish', () => {
httpRequestCounter.inc({
method: req.method,
route: req.path,
status: res.statusCode
});
});
next();
});
app.get('/', (req, res) => {
res.send('Aplicação funcionando!');
});
// Endpoint que o Prometheus vai ler
app.get('/metrics', async (req, res) => {
res.setHeader('Content-Type', client.register.contentType);
res.send(await client.register.metrics());
});
app.listen(port, () => {
console.log(`App rodando em http://localhost:${port}`);
});
Exemplo 2: Instrumentação em Java com Spring Boot e Micrometer
No ecossistema Java, o Spring Boot facilita esse processo através do módulo Spring Boot Actuator combinado com o Micrometer.
Adicione as seguintes dependências no seu arquivo pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
Em seguida, configure o arquivo application.properties para expor o endpoint do Prometheus:
management.endpoints.web.exposure.include=prometheus,health
management.endpoint.prometheus.enabled=true
management.metrics.tags.application=minha-app-java
A partir disso, o endpoint http://localhost:8080/actuator/prometheus estará ativo e pronto para ser consumido pelo Prometheus.
Atualizando o prometheus.yml
Para que o Prometheus passe a coletar os dados dessas aplicações, adicione-as na seção scrape_configs do arquivo prometheus.yml:
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-app'
metrics_path: '/metrics'
static_configs:
- targets: ['host.docker.internal:3000'] # host.docker.internal aponta para a máquina local de dentro do container
- job_name: 'java-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8080']
Nota: Reinicie o container do Prometheus (docker compose restart prometheus) para aplicar as novas configurações.
Criando Dashboards Eficazes no Grafana
Com as métricas sendo salvas no Prometheus, o próximo passo é visualizá-las no Grafana.
- Acesse
http://localhost:3000. - No menu lateral esquerdo, navegue até Connections > Data Sources.
- Clique em Add data source e selecione Prometheus.
- No campo Connection, insira a URL do Prometheus. Se estiver rodando via Docker Compose na mesma rede, use
http://prometheus:9090. - Role até o final da página e clique em Save & test. Se tudo estiver correto, uma mensagem verde de sucesso será exibida.
Boas Práticas de Design de Dashboards
Um erro comum ao iniciar no Grafana é criar painéis poluídos, cheios de gráficos coloridos que não ajudam na tomada de decisão rápida. Para evitar a fadiga visual e focar no que realmente importa, adote o método RED para serviços de requisição:
- Rate (Taxa): O volume de requisições por segundo que seu serviço está processando.
- Errors (Erros): A quantidade de requisições que estão falhando (ex: HTTP 5xx).
- Duration (Duração): O tempo que essas requisições estão levando para serem processadas (latência).
Para monitorar recursos de infraestrutura (servidores, bancos de dados), utilize o método USE:
- Utilization (Utilização): Média de tempo em que o recurso esteve ocupado (ex: CPU em 75%).
- Saturation (Saturação): O gargalo do recurso, ou seja, trabalho extra que ficou na fila (ex: fila de I/O de disco).
- Errors (Erros): Contagem de eventos de erro físicos ou lógicos.
No Grafana, você pode criar gráficos utilizando consultas PromQL. Por exemplo, para calcular a taxa de requisições HTTP por segundo nos últimos 5 minutos na sua aplicação Node.js, utilize a seguinte query no painel:
rate(http_requests_total[5m])
Configurando Alertas Inteligentes com o Alertmanager
Dashboards são excelentes para investigações ativas, mas ninguém deve ficar olhando para uma tela o dia inteiro esperando um erro acontecer. É aqui que entra o Alertmanager, o componente do ecossistema Prometheus responsável por gerenciar, agrupar e encaminhar alertas para ferramentas como Slack, Discord, e-mail ou PagerDuty.
Definindo Regras de Alerta no Prometheus
Crie um arquivo chamado alert.rules.yml no mesmo diretório do seu projeto:
groups:
- name: alertas_aplicacao
rules:
- alert: AltaTaxaDeErro5xx
expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100 > 5
for: 2m
labels:
severity: critical
annotations:
summary: "Alta taxa de erros HTTP 5xx detectada"
description: "A aplicação está respondendo com erro 5xx em mais de 5% das requisições nos últimos 2 minutos."
Essa regra calcula a porcentagem de erros HTTP 5xx em relação ao total de requisições. Se esse valor passar de 5% por mais de 2 minutos (for: 2m), o alerta é disparado.
Para carregar essa regra, atualize o seu prometheus.yml adicionando a seção rule_files:
global:
scrape_interval: 15s
rule_files:
- "alert.rules.yml"
scrape_configs:
Não se esqueça de mapear o arquivo alert.rules.yml no volume do Prometheus dentro do seu docker-compose.yml para que ele consiga ler as regras.
Desafios Comuns na Implementação e Como Superá-los
Embora a stack Prometheus e Grafana seja extremamente robusta, o crescimento da sua infraestrutura trará desafios técnicos que precisam ser planejados:
1. Alta Cardinalidade
Cardinalidade refere-se ao número de combinações únicas de labels (etiquetas) em suas métricas. Por exemplo, se você criar uma métrica de requisições HTTP e adicionar o ID do usuário como label (user_id), cada usuário único gerará uma nova série temporal no banco de dados do Prometheus.
Isso causará uma explosão de memória no Prometheus, podendo derrubar o serviço. Regra de ouro: Nunca use dados dinâmicos de alta variabilidade (como IDs de usuários, e-mails, UUIDs ou tokens) como labels de métricas. Use logs ou traces para esse nível de granularidade.
2. Retenção de Dados e Armazenamento
O Prometheus foi desenhado para ser um banco de dados de curto a médio prazo (por padrão, ele retém dados por 15 dias). Ele não deve ser usado como um data warehouse de métricas históricas de anos.
Se o seu time precisa de análises históricas de longo prazo, adote soluções de armazenamento distribuído compatíveis com o Prometheus, como Thanos, Cortex ou Mimir. Eles permitem persistir dados antigos de forma barata em storages de objetos (como AWS S3) mantendo a capacidade de consulta via PromQL.
Conclusão
A implementação de uma stack de observabilidade com Prometheus e Grafana transforma a forma como os times de tecnologia lidam com a estabilidade de seus sistemas. Em vez de reagir a reclamações de clientes, a engenharia passa a atuar de forma proativa, identificando anomalias de performance antes que elas se tornem indisponibilidades.
Comece pequeno: configure o ambiente local via Docker, instrumente as rotas principais da sua aplicação e crie um dashboard simples com as métricas RED. Conforme a maturidade do time aumentar, integre logs e traces para obter uma visão holística e resiliente de toda a sua infraestrutura.
Referências e Leituras Recomendadas
- Documentação Oficial do Prometheus
- Documentação Oficial do Grafana
- Os Três Pilares da Observabilidade - Grafana Labs
- Guia de Exporters do Prometheus
FAQ (Perguntas Frequentes)
Qual é a diferença prática entre monitoramento e observabilidade?
O monitoramento avisa quando algo dá errado com base em regras predefinidas (ex: CPU acima de 90%). A observabilidade permite que você investigue o comportamento interno do sistema e entenda o “porquê” de um comportamento anômalo inédito, correlacionando métricas, logs e traces.
O Prometheus consome muitos recursos da aplicação monitorada?
Não. Como o Prometheus utiliza um modelo de “pull” (ele busca as métricas expostas em um endpoint HTTP leve), o impacto de performance na aplicação é extremamente baixo, limitando-se à atualização das variáveis de contagem na memória RAM da aplicação.
Como evitar alertas redundantes ou fadiga de alertas no Alertmanager?
A melhor prática é focar alertas em sintomas que afetam diretamente a experiência do usuário final (ex: taxa de erro HTTP 5xx alta ou latência acima do aceitável) em vez de causas raiz isoladas (ex: uso temporário de CPU). Use agrupamento e inibição de alertas no Alertmanager para evitar notificações duplicadas de um mesmo incidente.
Sobre Marcos Costa
Desenvolvedor backend com foco em arquitetura de software, automação e produtos digitais.
Ver mais artigos