Pular para o conteúdo
Automação

Observabilidade total: métricas, logs e alertas com Prometheus e Grafana

Admin5 min de leitura
Observabilidade total: métricas, logs e alertas com Prometheus e Grafana

Observabilidade total: métricas, logs e alertas com Prometheus e Grafana

Resumo: Este artigo apresenta, de forma prática e detalhada, como montar uma stack de observabilidade usando Prometheus, Grafana e Alertmanager. Você aprenderá a coletar métricas, centralizar logs estruturados, criar dashboards interativos e configurar alertas inteligentes que reduzem o MTTR (Mean Time To Recovery) das suas aplicações.

Tecnologia e Inovação

Introdução

Em ambientes de produção modernos, a simples monitoração de disponibilidade já não é suficiente. Equipes de SRE e desenvolvedores precisam de observabilidade – a capacidade de entender o que está acontecendo dentro de um sistema a partir de seus sinais externos (métricas, logs e rastreamentos). Quando bem implementada, a observabilidade permite:

Detecção precoce de anomalias antes que usuários finais percebam o problema. Diagnóstico rápido, reduzindo o tempo de investigação. Feedback contínuo para melhorar a arquitetura e o código.

Neste artigo, vamos montar uma solução completa baseada em ferramentas open source amplamente adotadas no mercado: Prometheus para coleta de métricas, Grafana para visualização e Alertmanager para orquestração de alertas. Também abordaremos a ingestão de logs estruturados usando Loki, o parceiro de logs da Grafana Labs, garantindo que métricas e logs estejam disponíveis no mesmo painel.

Dica: Se ainda não tem nenhum dos componentes instalados, recomendamos usar o Docker Compose apresentado ao final para levantar tudo em poucos minutos.


1. Conceitos fundamentais de observabilidade

Antes de mergulharmos na prática, vale reforçar três pilares que sustentam a observabilidade:

PilarO que éPor que importa
MétricasValores numéricos ao longo do tempo (ex.: latência, taxa de erro).Permitem detectar tendências e disparar alertas baseados em limites.
Logs estruturadosTexto em formato JSON ou similar, contendo chaves e valores.Facilitam a correlação de eventos e a busca avançada.
Rastreamentos (opcional)Cadeia de chamadas distribuídas entre serviços.Ajudam a identificar gargalos em arquiteturas complexas.

Neste tutorial focaremos nos dois primeiros, que já são suficientes para cobrir a maioria dos casos de uso em sistemas web e APIs.


2. Coletando métricas com Prometheus

2.1 O que é o Prometheus?

Prometheus é um time‑series database (TSDB) que coleta métricas via HTTP em um formato chamado exposição. Ele funciona no modelo pull: periodicamente, o servidor Prometheus faz requisições a endpoints /metrics dos alvos configurados.

2.2 Configurando o Prometheus

Crie um diretório chamado observability e dentro dele um arquivo prometheus.yml:

# prometheus.yml

global: scrape_interval: 15s # frequência padrão de coleta evaluation_interval: 15s # frequência de avaliação de regras

scrape_configs: # 1️⃣ Alvo da aplicação Node.js (exemplo abaixo) - job_name: 'node_app' static_configs: - targets: ['host.docker.internal:9100']

# 2️⃣ Exporter do sistema (cAdvisor) para métricas de containers - job_name: 'cadvisor' static_configs: - targets: ['cadvisor:8080']

# 3️⃣ Exporter do Loki para métricas de ingestão de logs - job_name: 'loki' static_configs: - targets: ['loki:3100']

Observação: host.docker.internal permite que o container do Prometheus acesse o host local (útil para desenvolvimento).

2.3 Expondo métricas em uma aplicação Node.js

Instale o cliente oficial:

npm install prom-client

Em seguida, adicione o seguinte código ao seu servidor Express:

// metrics.js

const client = require('prom-client'); const express = require('express'); const app = express();

// Cria um Registry padrão const register = new client.Registry();

// Métrica de contagem de requisições HTTP const httpRequestsTotal = new client.Counter({ name: 'http_requests_total', help: 'Total de requisições HTTP recebidas', labelNames: ['method', 'route', 'code'], });

// Métrica de latência (histograma) const httpRequestDuration = new client.Histogram({ name: 'http_request_duration_seconds', help: 'Duração das requisições HTTP em segundos', labelNames: ['method', 'route', 'code'], buckets: [0.05, 0.1, 0.3, 0.5, 1, 3, 5], });

register.registerMetric(httpRequestsTotal); register.registerMetric(httpRequestDuration); client.collectDefaultMetrics({ register });

app.use((req, res, next) => { const end = httpRequestDuration.startTimer(); res.on('finish', () => { httpRequestsTotal.inc({ method: req.method, route: req.path, code: res.statusCode }); end({ method: req.method, route: req.path, code: res.statusCode }); }); next(); });

// Endpoint de métricas app.get('/metrics', async (req, res) => { res.set('Content-Type', register.contentType); res.end(await register.metrics()); });

module.exports = app;

Integre ao seu server.js:

// server.js

const http = require('http'); const app = require('./metrics');

const server = http.createServer(app); server.listen(9100, () => { console.log('Servidor rodando em http://localhost:9100'); });

Agora, ao iniciar a aplicação, o Prometheus conseguirá coletar as métricas em http://localhost:9100/metrics.

2.4 Regras de gravação (recording rules)

Para evitar cálculos pesados em tempo real, podemos pré‑agregar métricas:

# rules.yml

groups: - name: latency_rules interval: 30s rules: - record: job:http_request_duration_seconds:avg_5m expr: avg_over_time(http_request_duration_seconds[5m])

Inclua o arquivo nas rule_files do prometheus.yml:

rule_files:

- "rules.yml"


3. Centralizando logs com Loki e Grafana

3.1 Por que Loki?

Loki foi projetado para ser compatível com Prometheus: as mesmas labels usadas nas métricas podem ser reutilizadas nos logs, facilitando a correlação. Diferente de soluções de busca genéricas, Loki armazena apenas os metadados (labels) e delega o conteúdo dos logs a um armazenamento de objetos (ex.: S3, MinIO).

3.2 Configurando Loki via Docker Compose

# docker-compose.yml (trecho)

services: loki: image: grafana/loki:2.9.1 command: -config.file=/etc/loki/local-config.yaml ports: - "3100:3100" volumes: - ./loki-config.yaml:/etc/loki/local-config.yaml

promtail: image: grafana/promtail:2.9.1 volumes: - /var/log:/var/log - ./promtail-config.yaml:/etc/promtail/config.yaml command: -config.file=/etc/promtail/config.yaml

promtail-config.yaml – agente que envia logs para o Loki:

server:

http_listen_port: 9080 grpc_listen_port: 0

positions: filename: /tmp/positions.yaml

clients: - url: http://loki:3100/loki/api/v1/push

scrape_configs: - job_name: system static_configs: - targets: - localhost labels: job: varlogs __path__: /var/log//.log

3.3 Logs estruturados na aplicação Node.js

Modifique o código para usar pino, que já gera JSON:

npm install pino pino-http
// logger.js

const pino = require('pino'); const logger = pino({ level: 'info', base: { pid: process.pid }, timestamp: () => ,"time":"${new Date().toISOString()}", });

module.exports = logger;

Integre ao Express:

// server.js (continuação)

const logger = require('./logger'); app.use(require('pino-http')({ logger }));

app.get('/hello', (req, res) => { logger.info({ route: '/hello', method: req.method }, 'Endpoint acessado'); res.send('Olá Mundo!'); });

Agora, os logs são enviados ao stdout em formato JSON. O promtail captura o stdout (se configurado) ou arquivos de log e os encaminha ao Loki.

3.4 Visualizando métricas e logs no Grafana

Instale o Grafana via Docker:

```yaml grafana: image: grafana/grafana:10.2.0 ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin volumes: - grafana-data:/var/lib/grafana

Artigos relacionados