TP11.2 - Monitoramento com Prometheus & Grafana
Objetivos do Exercício
Neste exercício, você irá:
- ✅ Configurar o Prometheus para coletar as métricas
- ✅ Criar dashboards no Grafana
- ✅ Visualizar as métricas da aplicação
- ✅ Configurar alertas
Duração estimada: 1h30
Pré-requisitos: Docker instalado, TP11.1 concluído
Contexto
Você irá implementar uma stack completa de monitoramento para a aplicação e-commerce do TP1.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Spring Boot │────▶│ Prometheus │────▶│ Grafana │
│ /actuator │ │ (Coleta) │ │ (Visualização) │
│ /prometheus │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Parte 1: Docker Compose
Estrutura do Projeto
project/
├── src/
├── pom.xml
├── docker-compose.yml
├── prometheus/
│ └── prometheus.yml
└── grafana/
└── provisioning/
└── datasources/
└── datasource.yml
docker-compose.yml
version: '3.8'
services:
# Sua aplicação Spring Boot
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=docker
networks:
- monitoring
# Prometheus - Coleta de métricas
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
networks:
- monitoring
# Grafana - Visualização
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
depends_on:
- prometheus
networks:
- monitoring
volumes:
prometheus_data:
grafana_data:
networks:
monitoring:
driver: bridge
Parte 2: Configuração do Prometheus
prometheus/prometheus.yml
global:
scrape_interval: 15s # Frequência de coleta
evaluation_interval: 15s # Frequência de avaliação das regras
scrape_configs:
# Prometheus coleta suas próprias métricas
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# Aplicação Spring Boot
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
scrape_interval: 10s
static_configs:
- targets: ['app:8080'] # 'app' = nome do serviço Docker
labels:
application: 'ecommerce-app'
environment: 'development'
# Se você executar o app localmente (fora do Docker)
# - job_name: 'spring-boot-local'
# metrics_path: '/actuator/prometheus'
# static_configs:
# - targets: ['host.docker.internal:8080']
Parte 3: Configuração do Grafana
grafana/provisioning/datasources/datasource.yml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
Parte 4: Inicializando a Stack
Iniciar os Serviços
# Iniciar a stack
docker-compose up -d
# Verificar os logs
docker-compose logs -f
# Verificar se tudo está funcionando
curl http://localhost:8080/actuator/prometheus # App
curl http://localhost:9090/targets # Prometheus
# Grafana: http://localhost:3000 (admin/admin)
Sem Docker (App local)
Se você executar o app fora do Docker:
# prometheus.yml - Modificar o target
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8080']
Parte 5: Verificar o Prometheus
Acessar o Prometheus
Verificar os Targets
Vá em Status → Targets
Você deve ver:
spring-boot-appcom statusUP
Consultas PromQL
Teste estas consultas na aba Graph:
# Memória JVM utilizada
jvm_memory_used_bytes{area="heap"}
# Requisições HTTP por segundo
rate(http_server_requests_seconds_count[5m])
# Latência P99
histogram_quantile(0.99, rate(http_server_requests_seconds_bucket[5m]))
# Pedidos pendentes
business_orders_pending
# Produtos com baixo estoque
business_products_low_stock
Parte 6: Criar um Dashboard no Grafana
Conexão
- Abra http://localhost:3000
- Login:
admin/admin - Altere a senha
Criar um Dashboard
- Clique em + → Dashboard
- Clique em Add visualization
- Selecione Prometheus como fonte de dados
Painel 1: Requisições/Segundo
Query:
sum(rate(http_server_requests_seconds_count{application="ecommerce-app"}[5m]))
Configurações:
- Título: "Requests per Second"
- Tipo: Stat ou Time series
Painel 2: Latência P95
Query:
histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket{application="ecommerce-app"}[5m])) by (le))
Configurações:
- Título: "P95 Latency"
- Unidade: seconds (s)
Painel 3: Memória JVM
Query:
jvm_memory_used_bytes{area="heap", application="ecommerce-app"} / 1024 / 1024
Configurações:
- Título: "Heap Memory Used (MB)"
- Unidade: megabytes
Painel 4: Pedidos por Status
Queries:
business_orders_pending
business_orders_completed
business_orders_cancelled
Configurações:
- Título: "Orders by Status"
- Tipo: Stat (com repeat para cada query)
Painel 5: Produtos com Baixo Estoque
Query:
business_products_low_stock
Configurações:
- Título: "Products with Low Stock"
- Tipo: Gauge
- Thresholds: 0-5 verde, 5-10 amarelo, 10+ vermelho
Painel 6: Receita Total
Query:
business_revenue_total
Configurações:
- Título: "Total Revenue"
- Unidade: Currency ($)
Parte 7: Dashboard JSON (Importação)
Você pode importar este dashboard pré-configurado:
{
"title": "E-Commerce Application",
"panels": [
{
"title": "Requests/sec",
"type": "stat",
"targets": [
{
"expr": "sum(rate(http_server_requests_seconds_count[5m]))",
"refId": "A"
}
],
"gridPos": {"h": 4, "w": 6, "x": 0, "y": 0}
},
{
"title": "P95 Latency",
"type": "gauge",
"targets": [
{
"expr": "histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le))",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {"unit": "s", "thresholds": {"steps": [{"value": 0, "color": "green"}, {"value": 0.5, "color": "yellow"}, {"value": 1, "color": "red"}]}}
},
"gridPos": {"h": 4, "w": 6, "x": 6, "y": 0}
},
{
"title": "Heap Memory (MB)",
"type": "timeseries",
"targets": [
{
"expr": "jvm_memory_used_bytes{area=\"heap\"} / 1024 / 1024",
"refId": "A"
}
],
"fieldConfig": {"defaults": {"unit": "decmbytes"}},
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 0}
},
{
"title": "Orders Pending",
"type": "stat",
"targets": [{"expr": "business_orders_pending", "refId": "A"}],
"gridPos": {"h": 4, "w": 4, "x": 0, "y": 4}
},
{
"title": "Low Stock Products",
"type": "stat",
"targets": [{"expr": "business_products_low_stock", "refId": "A"}],
"fieldConfig": {
"defaults": {"thresholds": {"steps": [{"value": 0, "color": "green"}, {"value": 5, "color": "yellow"}, {"value": 10, "color": "red"}]}}
},
"gridPos": {"h": 4, "w": 4, "x": 4, "y": 4}
},
{
"title": "Total Revenue",
"type": "stat",
"targets": [{"expr": "business_revenue_total", "refId": "A"}],
"fieldConfig": {"defaults": {"unit": "currencyUSD"}},
"gridPos": {"h": 4, "w": 4, "x": 8, "y": 4}
}
],
"refresh": "10s",
"time": {"from": "now-1h", "to": "now"}
}
Para importar:
- Dashboard → Import
- Cole o JSON
- Selecione a fonte de dados Prometheus
- Importar
Parte 8: Gerar Tráfego
Script de Teste
#!/bin/bash
# generate-traffic.sh
API_URL="http://localhost:8080"
# Criar pedidos
for i in {1..20}; do
curl -X POST "$API_URL/api/orders" \
-H "Content-Type: application/json" \
-d "{\"customerEmail\":\"user$i@test.com\",\"total\":$((RANDOM % 500 + 100))}"
sleep 0.5
done
# Consultar produtos
for i in {1..50}; do
curl "$API_URL/api/products" > /dev/null 2>&1
sleep 0.2
done
echo "Traffic generated!"
Execute o script e observe as métricas no Grafana.
Parte 9: Alertas (Bônus)
Adicionar Alertas no Grafana
- Vá em um painel (ex: Low Stock Products)
- Clique em Alert → Create alert rule
- Configure:
- Condição:
query A > 10 - Avaliar a cada: 1m
- Por: 5m (deve ser verdadeiro por 5 min)
- Condição:
- Adicione uma notificação (email, Slack, etc.)
Alertas no Prometheus
Crie prometheus/alert.rules.yml:
groups:
- name: spring-boot-alerts
rules:
- alert: HighMemoryUsage
expr: jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "High memory usage detected"
description: "Heap memory is above 90%"
- alert: HighErrorRate
expr: sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) / sum(rate(http_server_requests_seconds_count[5m])) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "High error rate"
description: "Error rate is above 5%"
- alert: LowStock
expr: business_products_low_stock > 10
for: 10m
labels:
severity: warning
annotations:
summary: "Many products with low stock"
Checklist Final
- Docker Compose inicia sem erro
- Prometheus coleta a aplicação (Target UP)
- Métricas visíveis no Prometheus
- Dashboard do Grafana funcional
- Métricas de negócio (orders, products) exibidas
- Atualização automática do dashboard
🎯 Módulo Concluído!
Parabéns! Você concluiu o Módulo 11 - Spring Boot Actuator e Monitoramento.
Resumo:
- Capítulo 1: Introdução ao Actuator
- Capítulo 2: Endpoints
- Capítulo 3: Métricas Micrometer
- Capítulo 4: Health Checks
- TP1: Configuração do Actuator
- TP2: Prometheus & Grafana
Competências adquiridas:
- ✅ Configuração completa do Actuator
- ✅ Health checks personalizados
- ✅ Métricas de negócio com Micrometer
- ✅ Stack de monitoramento Prometheus/Grafana
- ✅ Dashboards e visualizações