Spring Boot Actuator
O Actuator é o painel do Spring Boot—fornece status de saúde, métricas e informações de configuração—e oferece às equipes de operações uma "visão panorâmica."
1. O Que Você Vai Aprender
- Visão Geral dos Endpoints do Actuator:
/health//info//metrics//env//beans - Habilitação e Política de Exposição de Endpoints:
management.endpoints.web.exposure.include - HealthIndicator personalizado para monitorar conectividade do banco de dados com serviços externos
@ReadOperation/@WriteOperationEndpoints Personalizados- Fortalecimento de Segurança: Controle de Acesso a Endpoints e Segmentação de Rede
2. Uma História Real de um Engenheiro de Operações
(1) Dor: O ambiente de produção é como uma caixa preta
Bob é responsável pelas operações e manutenção do ambiente de produção do OrderFlow, mas a aplicação é uma caixa preta completa para ele: As conexões com o banco de dados estão funcionando corretamente? Quanta memória está sendo usada? Quais APIs estão respondendo lentamente? Toda vez que surge um problema, ele precisa pedir à Alice para adicionar logs ou reiniciar a aplicação para solucioná-lo, resultando em um Tempo Médio de Recuperação (MTTR) de mais de 1 hora. Charlie exigiu que o MTTR fosse reduzido para 10 minutos.
(2) Solução com o Actuator
O Actuator está pronto para uso imediato e oferece uma ampla variedade de endpoints de operações e manutenção:
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
curl http://localhost:8080/actuator/health
# {"status":"UP","components":{"db":{"status":"UP"},"diskSpace":{"status":"UP"}}}
(3) Resultado
Depois que Bob começou a usar o Actuator, /health monitorou a conectividade do banco de dados, /metrics acompanhou os tempos de resposta das APIs, e um HealthIndicator personalizado verificou o gateway de pagamento externo, reduzindo o MTTR de 1 hora para 5 minutos.
3. Visão Geral dos Endpoints do Actuator
(1) Lista de Endpoints Integrados
| Endpoint | Descrição | Exposição Padrão |
|---|---|---|
/actuator/health |
Status de Saúde da Aplicação | ✅ Sim |
/actuator/info |
Informações da Aplicação | ✅ Sim |
/actuator/metrics |
Lista de Indicadores | ❌ Não |
/actuator/metrics/{name} |
Valor de métrica específica | ❌ Não |
/actuator/env |
Configuração de Ambiente | ❌ Não |
/actuator/beans |
Lista de Beans | ❌ Não |
/actuator/loggers |
Nível de Log | ❌ Não |
/actuator/threaddump |
Thread Dump | ❌ Não |
/actuator/heapdump |
Heap Dump | ❌ Não |
/actuator/prometheus |
Métricas no formato Prometheus | ❌ Não |
(1) ▶ Exemplo: Habilitando a dependência do Actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Saída:
// Execução bem-sucedida
(2) ▶ Exemplo: Configurando a Exposição de Endpoints
management:
endpoints:
web:
exposure:
include: health,info,metrics,env,loggers
base-path: /actuator
endpoint:
health:
show-details: when-authorized
metrics:
enabled: true
info:
env:
enabled: true
Saída:
A configuração entrou em vigor.
| Política de Exposição | Valor de Configuração | Descrição |
|---|---|---|
| Apenas Saúde e Informações | include: health,info |
Mais seguro, Padrão |
| Exposição Sob Demanda | include: health,info,metrics |
Recomendado |
| Mostrar Tudo | include: "*" |
Apenas Ambiente de Desenvolvimento |
| Excluir Específicos | exclude: env,beans |
Excluir de Todos |
4. Explicação Detalhada do Endpoint de Saúde
(1) Regras de Agregação de Status de Saúde
graph TD
A["Agregador de<br/>Status de Saúde"] --> B["DiskSpace<br/>UP"]
A --> C["DataSource<br/>UP"]
A --> D["PaymentGateway<br/>DOWN"]
A --> E["Redis<br/>UP"]
D --> F["Geral: DOWN<br/>Qualquer DOWN → DOWN"]
| Status | Significado | Regras de Agregação |
|---|---|---|
| UP | Normal | — |
| DOWN | Exceção | Qualquer DOWN individual → Geral DOWN |
| DEGRADED | Degradado | Degradação de componente não crítico |
| OUT_OF_SERVICE | Serviço Indisponível | Qualquer um → Todos OUT_OF_SERVICE |
| UNKNOWN | Desconhecido | Padrão |
(1) ▶ Exemplo: HealthIndicator Personalizado
@Component
public class PaymentGatewayHealthIndicator implements HealthIndicator {
private final RestTemplate restTemplate;
public PaymentGatewayHealthIndicator(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public Health health() {
try {
ResponseEntity<String> response = restTemplate.getForEntity(
"https://api.payment-gateway.com/ping", String.class);
if (response.getStatusCode().is2xxSuccessful()) {
return Health.up()
.withDetail("gateway", "reachable")
.withDetail("responseTime", response.getHeaders().getDate())
.build();
}
return Health.down()
.withDetail("gateway", "unhealthy")
.withDetail("statusCode", response.getStatusCode())
.build();
} catch (Exception e) {
return Health.down()
.withDetail("gateway", "unreachable")
.withDetail("error", e.getMessage())
.build();
}
}
}
Saída:
// Execução bem-sucedida
{
"status": "DOWN",
"components": {
"diskSpace": {"status": "UP", "details": {"total": 536870912000, "free": 268435456000}},
"db": {"status": "UP", "details": {"database": "MySQL", "validationQuery": "SELECT 1"}},
"paymentGateway": {"status": "DOWN", "details": {"gateway": "unreachable", "error": "Connection refused"}}
}
}
5. Explicação Detalhada dos Endpoints de Métricas
(1) ▶ Exemplo: Visualizar métricas de requisições HTTP
# Listar todas as métricas disponíveis
curl http://localhost:8080/actuator/metrics
# Obter métrica específica: requisições do servidor HTTP
curl http://localhost:8080/actuator/metrics/http.server.requests
# Obter métrica filtrada
curl "http://localhost:8080/actuator/metrics/http.server.requests?tag=uri:/api/v1/orders&tag=status:200"
Saída:
{"status":"ok","data":{}}
| Métricas Comuns | Descrição |
|---|---|
http.server.requests |
Distribuição de Duração das Requisições HTTP |
jvm.memory.used |
Uso de Memória da JVM |
jvm.threads.live |
Número de Threads Ativas |
process.cpu.usage |
Uso de CPU do Processo |
disk.total / disk.free |
Espaço em Disco |
hikaricp.connections.active |
Pool de Conexões do Banco de Dados |
(2) ▶ Exemplo: Métricas de Negócio Personalizadas
@Service
public class OrderMetrics {
private final Counter orderCreatedCounter;
private final Timer orderCreationTimer;
private final AtomicLong pendingOrders;
public OrderMetrics(MeterRegistry registry) {
this.orderCreatedCounter = Counter.builder("orderflow.orders.created")
.description("Total de pedidos criados")
.tag("service", "orderflow")
.register(registry);
this.orderCreationTimer = Timer.builder("orderflow.orders.creation.time")
.description("Tempo de criação do pedido")
.register(registry);
this.pendingOrders = registry.gauge("orderflow.orders.pending",
new AtomicLong(0));
}
public void recordOrderCreated() {
orderCreatedCounter.increment();
pendingOrders.incrementAndGet();
}
public void recordOrderCompleted() {
pendingOrders.decrementAndGet();
}
public Timer getCreationTimer() {
return orderCreationTimer;
}
}
Saída:
// Execução bem-sucedida
6. Endpoints Personalizados
(1) ▶ Exemplo: Endpoint OrderStats Personalizado
@Endpoint(id = "orderstats")
@Component
public class OrderStatsEndpoint {
private final OrderRepository orderRepository;
public OrderStatsEndpoint(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@ReadOperation
public Map<String, Object> orderStats() {
long total = orderRepository.count();
long pending = orderRepository.countByStatus("PENDING");
long completed = orderRepository.countByStatus("COMPLETED");
long cancelled = orderRepository.countByStatus("CANCELLED");
return Map.of(
"totalOrders", total,
"pendingOrders", pending,
"completedOrders", completed,
"cancelledOrders", cancelled,
"completionRate", total > 0
? String.format("%.2f%%", (double) completed / total * 100)
: "N/A"
);
}
@ReadOperation
public Map<String, Object> orderStatsByStatus(
@Selector String status) {
long count = orderRepository.countByStatus(status.toUpperCase());
return Map.of("status", status, "count", count);
}
}
Saída:
// Execução bem-sucedida
management:
endpoint:
orderstats:
enabled: true
endpoints:
web:
exposure:
include: health,info,orderstats
curl http://localhost:8080/actuator/orderstats
# {"totalOrders":1523,"pendingOrders":45,"completedOrders":1420,"cancelledOrders":58,"completionRate":"93.30%"}
curl http://localhost:8080/actuator/orderstats/PENDING
# {"status":"PENDING","count":45}
7. Fortalecimento de Segurança
(1) Política de Segurança de Endpoints
| Nível | Política | Descrição |
|---|---|---|
| Camada de Rede | Porta de Gerenciamento Dedicada | management.server.port=8081 |
| Camada de Rede | Vincular a IP Interno | management.server.address=127.0.0.1 |
| Camada de Aplicação | Controle Spring Security | .requestMatchers("/actuator/**").hasRole("ADMIN") |
| Camada de Endpoint | Desabilitar Endpoints Sensíveis | management.endpoint.env.enabled=false |
(1) ▶ Exemplo: Configuração de Segurança em Nível de Produção
# application-prod.yml
management:
server:
port: 8081 # Porta de gerenciamento separada
address: 127.0.0.1 # Vincular apenas ao localhost
endpoints:
web:
exposure:
include: health,prometheus,orderstats
base-path: /actuator
endpoint:
health:
show-details: when-authorized
env:
enabled: false
beans:
enabled: false
heapdump:
enabled: false
Saída:
Configuração de monitoramento carregada
Alvos do Prometheus: 3 ativos
Dashboard do Grafana: pronto
| Ambiente | Política de Exposição | Porta de Gerenciamento |
|---|---|---|
| Desenvolvimento | include: "*" |
Porta 8080 |
| Teste | include: health,info,metrics,env |
Mesma porta 8080 |
| Produção | include: health,prometheus |
Porta Dedicada 8081 + Rede Interna |
8. Exemplo Abrangente: Configuração Completa do Actuator do OrderFlow
# application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus,orderstats
endpoint:
health:
show-details: when-authorized
orderstats:
enabled: true
metrics:
tags:
application: ${spring.application.name}
info:
env:
enabled: true
info:
app:
name: OrderFlow Service
version: @project.version@
description: Microsserviço de gerenciamento de pedidos de e-commerce
// PaymentGatewayHealthIndicator.java
@Component
public class PaymentGatewayHealthIndicator implements HealthIndicator {
private final RestTemplate restTemplate;
public PaymentGatewayHealthIndicator(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public Health health() {
try {
ResponseEntity<String> resp = restTemplate
.getForEntity("https://api.payment.com/ping", String.class);
return resp.getStatusCode().is2xxSuccessful()
? Health.up().withDetail("gateway", "reachable").build()
: Health.down().withDetail("statusCode", resp.getStatusCode()).build();
} catch (Exception e) {
return Health.down().withDetail("error", e.getMessage()).build();
}
}
}
// OrderStatsEndpoint.java
@Endpoint(id = "orderstats")
@Component
public class OrderStatsEndpoint {
private final OrderRepository orderRepository;
public OrderStatsEndpoint(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@ReadOperation
public Map<String, Object> stats() {
return Map.of(
"total", orderRepository.count(),
"pending", orderRepository.countByStatus("PENDING"),
"completed", orderRepository.countByStatus("COMPLETED")
);
}
}
❓ Perguntas Frequentes
/health é para balanceadores de carga e probes do K8s; não expõe detalhes sensíveis. /health com detalhes é destinado às equipes de operações e requer permissões de ADMIN. Use show-details: when-authorized em ambientes de produção.HealthAggregator ou use o bean StatusAggregator. A regra padrão é: Qualquer DOWN → Geral DOWN. Você pode personalizar a prioridade usando statusOrder./actuator/env expõe senhas?password, secret, key e token (exibindo ••••••). Ainda assim, é recomendado desabilitar este endpoint em ambientes de produção.micrometer-registry-prometheus, exponha o endpoint prometheus e adicione um alvo de coleta na configuração do Prometheus. Isso será abordado em detalhes em uma aula posterior (L23).📖 Resumo
- O Actuator fornece endpoints operacionais como saúde, métricas, configuração e threads; por padrão, apenas health e info são expostos.
- HealthIndicator personalizado para monitorar conectividade com serviços externos
- O endpoint de Métricas fornece métricas integradas para HTTP, JVM, pools de conexão e mais
- Endpoints personalizados usam
@Endpoint+@ReadOperation/@WriteOperation - Segurança em Produção: Porta de gerenciamento dedicada + Vinculação à rede interna + Exposição limitada + Spring Security
show-details: when-authorizedControla a exibição dos detalhes de saúde
📝 Exercícios
-
Exercício Básico (Dificuldade ⭐): Adicione o Actuator ao OrderFlow, configure-o para expor os endpoints health, info e metrics, e verifique se
/actuator/healthretorna o status "UP". -
Exercício Avançado (Dificuldade: ⭐⭐): Implemente um
PaymentGatewayHealthIndicatorpersonalizado e umOrderStatsEndpoint, e configure uma porta de gerenciamento separada para o ambiente de produção. -
Desafio (Dificuldade: ⭐⭐⭐): Adicione a dependência
micrometer-registry-prometheus, exponha o endpoint/actuator/prometheus, escreva métricas de negócio personalizadas (contagem de criação de pedidos, tempo de realização de pedidos) e considere convenções de nomenclatura e design de tags para as métricas.



