💻 Exemplos: Capítulo 19: Observabilidade com Spring Boot Actuator, Micrometer e Prometheus
Especialização em Backend com Java & Spring Boot • Demonstrações Práticas Compiláveis
💻 Código de Exemplo 01 — Configuração de Exposição do Actuator e Probes Kubernetes
# application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
probes:
enabled: true
health:
livenessstate:
enabled: true
readinessstate:
enabled: true
package com.empresa.api.controller;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
@Component
public class DiskSpaceBusinessHealthIndicator implements HealthIndicator {
@Override
public Health health() {
long espacoLivreMb = new java.io.File("/dados/uploads").getFreeSpace() / (1024 * 1024);
if (espacoLivreMb < 100) {
return Health.down().withDetail("espacoLivreMb", espacoLivreMb).build();
}
return Health.up().withDetail("espacoLivreMb", espacoLivreMb).build();
}
}
💻 Código de Exemplo 02 — Métricas Customizadas com Counter, Timer e Gauge
package com.empresa.api.metrics;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Service;
@Service
public class MetricService {
private final Counter pedidosCounter;
public MetricService(MeterRegistry registry) {
this.pedidosCounter = Counter.builder("pedidos_criados_total")
.description("Total de pedidos processados com sucesso")
.tag("ambiente", "producao")
.register(registry);
// Gauge: valor instantâneo (sobe e desce), útil para tamanhos de fila/pool em tempo real.
io.micrometer.core.instrument.Gauge.builder("fila_pedidos_pendentes",
this, MetricService::contarPedidosPendentes)
.description("Quantidade atual de pedidos aguardando processamento")
.register(registry);
}
public void registrarNovoPedido() {
pedidosCounter.increment();
}
private double contarPedidosPendentes() {
return 0; // substituído por consulta real ao repositório/fila em produção
}
}
package com.empresa.api.controller;
import com.empresa.api.metrics.MetricService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PedidoController {
private final MetricService metricService;
public PedidoController(MetricService metricService) {
this.metricService = metricService;
}
@PostMapping("/api/v1/pedidos")
public void criarPedido() {
// lógica de criação do pedido...
metricService.registrarNovoPedido(); // incrementa "pedidos_criados_total" no Prometheus
}
}
💻 Código de Exemplo 03 — Tracing Distribuído com Micrometer Tracing e MDC
package com.empresa.api.metrics;
import io.micrometer.tracing.Tracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class TracingLogger {
private static final Logger log = LoggerFactory.getLogger(TracingLogger.class);
private final Tracer tracer;
public TracingLogger(Tracer tracer) {
this.tracer = tracer;
}
public void logComTrace(String mensagem) {
// traceId permanece o mesmo em todos os serviços atravessados pela requisição;
// spanId é único por etapa — ambos ficam disponíveis no MDC automaticamente.
var span = tracer.currentSpan();
if (span != null) {
log.info("[traceId={}, spanId={}] {}",
span.context().traceId(), span.context().spanId(), mensagem);
} else {
log.info(mensagem);
}
}
}
# application.properties — padrão de log incluindo traceId/spanId via MDC automático
logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
management.tracing.sampling.probability=1.0
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans