Como monitorar aplicações com Prometheus
1. Introdução ao Prometheus e conceitos fundamentais
Prometheus é um sistema de monitoramento e alerta de código aberto, originalmente desenvolvido pela SoundCloud e atualmente parte da Cloud Native Computing Foundation (CNCF). Sua arquitetura baseada em pull (coleta ativa de métricas) o diferencia de ferramentas tradicionais que utilizam push (agentes enviando dados). O modelo de séries temporais armazena cada métrica como um conjunto de pontos no tempo identificados por labels (pares chave-valor), permitindo consultas flexíveis e agregações poderosas.
Métricas, labels e cardinalidade são conceitos centrais. Uma métrica como http_requests_total pode ter labels method, endpoint e status. A cardinalidade é o número de combinações únicas de labels — se você adicionar um label com valores dinâmicos como user_id, pode causar explosão de séries temporais, sobrecarregando o armazenamento.
Comparado a Zabbix (monitoramento mais tradicional, focado em hosts) ou Datadog/New Relic (SaaS com agentes push), Prometheus oferece maior controle sobre dados, integração nativa com Kubernetes e ecossistema rico de exporters.
2. Instalação e configuração inicial do Prometheus
A forma mais rápida de testar Prometheus é via Docker:
docker run -d --name prometheus -p 9090:9090 prom/prometheus
Para configuração persistente, crie um arquivo prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
Monte o arquivo no container:
docker run -d --name prometheus -p 9090:9090 -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
No Kubernetes, utilize o operador oficial ou um deployment simples. Acesse a interface web em http://localhost:9090. As páginas /targets mostram o status de cada alvo de coleta, e /graph permite consultas PromQL.
3. Instrumentação de aplicações com client libraries
As client libraries oficiais (Go, Java, Python, Ruby, Rust) expõem métricas em formato texto no endpoint /metrics. Os quatro tipos principais são:
- Counter: valor que só aumenta (ex: requisições totais)
- Gauge: valor que pode subir e descer (ex: memória usada)
- Histogram: distribuição de valores em buckets (ex: latência)
- Summary: percentis calculados no cliente (ex: latência p99)
Exemplo prático: instrumentar uma API Flask em Python.
Instale a biblioteca:
pip install prometheus-client
Código da aplicação:
from flask import Flask, request
from prometheus_client import Counter, Histogram, generate_latest, REGISTRY
import time
app = Flask(__name__)
REQUESTS = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint', 'status'])
LATENCY = Histogram('http_request_duration_seconds', 'HTTP request latency', ['method', 'endpoint'])
@app.route('/api/health')
def health():
start = time.time()
status = 200
REQUESTS.labels(method='GET', endpoint='/api/health', status=status).inc()
LATENCY.labels(method='GET', endpoint='/api/health').observe(time.time() - start)
return 'OK', status
@app.route('/metrics')
def metrics():
return generate_latest(REGISTRY), 200, {'Content-Type': 'text/plain'}
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Adicione a aplicação como target no prometheus.yml:
scrape_configs:
- job_name: 'flask_app'
static_configs:
- targets: ['localhost:5000']
4. Exporters essenciais para infraestrutura e serviços
Exporters são bridges que expõem métricas de sistemas que não possuem client library nativa.
Node Exporter — Métricas de sistema operacional (CPU, memória, disco, rede):
docker run -d --name node_exporter -p 9100:9100 prom/node-exporter
Blackbox Exporter — Monitoramento de endpoints HTTP, TCP, ICMP:
docker run -d --name blackbox_exporter -p 9115:9115 prom/blackbox-exporter
Configuração no prometheus.yml:
scrape_configs:
- job_name: 'blackbox_http'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets: ['https://example.com']
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: localhost:9115
Exporters para bancos de dados incluem postgres_exporter, mysqld_exporter, redis_exporter e para message brokers como kafka_exporter.
5. Descoberta de serviços e targets dinâmicos
Em ambientes Kubernetes, o service discovery automático é essencial:
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
Para ambientes estáticos, use file_sd_configs:
scrape_configs:
- job_name: 'custom_services'
file_sd_configs:
- files: ['/etc/prometheus/targets/*.json']
Arquivo JSON de exemplo:
[
{"targets": ["192.168.1.10:9100", "192.168.1.11:9100"], "labels": {"env": "production"}}
]
relabel_configs e metric_relabel_configs permitem filtrar, renomear e modificar labels antes do armazenamento.
6. Consultas com PromQL para análise de métricas
PromQL (Prometheus Query Language) é a linguagem de consulta. Exemplos práticos:
Taxa de requisições por segundo:
rate(http_requests_total[5m])
Latência média dos últimos 10 minutos:
avg(rate(http_request_duration_seconds_sum[10m]) / rate(http_request_duration_seconds_count[10m]))
Percentil 99 de latência:
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
Uso de CPU por instância:
100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
Regras de gravação para otimizar consultas complexas:
groups:
- name: recording_rules
rules:
- record: job:http_requests:rate5m
expr: rate(http_requests_total[5m])
7. Alertas com Alertmanager e integrações
Defina regras de alerta no prometheus.yml:
rule_files:
- 'alerts.yml'
Arquivo alerts.yml:
groups:
- name: instance_alerts
rules:
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "Instance {{ $labels.instance }} has been down for more than 5 minutes."
Configure o Alertmanager (alertmanager.yml):
route:
receiver: 'slack'
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: 'slack'
slack_configs:
- api_url: 'https://hooks.slack.com/services/TOKEN'
channel: '#alerts'
Integrações com PagerDuty, e-mail e webhooks seguem padrão similar.
8. Boas práticas e otimização de desempenho
Gerenciamento de cardinalidade: evite labels com valores ilimitados (user IDs, e-mails). Use labels como method, status, endpoint que têm valores previsíveis.
Retenção de dados: por padrão, Prometheus retém 15 dias localmente. Para períodos maiores, use armazenamento remoto como Thanos ou Cortex:
--storage.tsdb.retention.time=30d
Estratégias de scrape: ajuste scrape_interval conforme a criticidade. Métricas de infraestrutura podem usar 15s; métricas de negócio, 30s ou mais.
Otimização: evite consultas sem intervalos de tempo (ex: http_requests_total sem [5m]), use recording rules para consultas frequentes e monitore o próprio Prometheus com métricas como prometheus_target_interval_length_seconds.
Referências
- Documentação oficial do Prometheus — Guia completo de conceitos, configuração e operação.
- Prometheus Client Library para Python — Repositório oficial com exemplos de instrumentação.
- Node Exporter — Exporter para métricas de sistema Linux/Windows.
- Blackbox Exporter — Monitoramento de endpoints HTTP, TCP, ICMP e DNS.
- PromQL Cheat Sheet — Referência visual de operadores e funções PromQL.
- Alertmanager Configuration — Documentação de roteamento e integrações de alertas.
- Thanos - Armazenamento de longo prazo — Solução para retenção global e consultas multi-cluster.