Quiz: Spring Boot Actuator
Ponga a prueba sus conocimientos sobre Actuator, métricas y monitoreo.
30 preguntas - Haga clic en cada pregunta para revelar la respuesta.
Preguntas 1-15: Fundamentos de Actuator
Pregunta 1: ¿Qué es Spring Boot Actuator?
Respuesta: Actuator proporciona endpoints para monitorear y gestionar una aplicación Spring Boot en producción:
- Estado de la aplicación
- Métricas
- Información sobre el entorno
- Gestión de logs
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Pregunta 2: ¿Cómo exponer todos los endpoints de Actuator?
Respuesta:
management:
endpoints:
web:
exposure:
include: "*"
Por defecto, solo /health y /info están expuestos.
Pregunta 3: ¿Cuáles son los principales endpoints de Actuator?
Respuesta:
| Endpoint | Descripción |
|---|---|
/actuator/health | Estado de la aplicación |
/actuator/info | Información personalizada |
/actuator/metrics | Métricas |
/actuator/env | Propiedades de entorno |
/actuator/loggers | Niveles de log |
/actuator/beans | Beans de Spring |
/actuator/mappings | Rutas HTTP |
/actuator/threaddump | Hilos activos |
/actuator/heapdump | Volcado de memoria |
Pregunta 4: ¿Cómo configurar el endpoint health?
Respuesta:
management:
endpoint:
health:
show-details: always # never, when-authorized, always
show-components: always
health:
db:
enabled: true
diskspace:
enabled: true
threshold: 10MB
Pregunta 5: ¿Cómo crear un Health Indicator personalizado?
Respuesta:
@Component
public class ExternalApiHealthIndicator implements HealthIndicator {
private final ExternalApiClient apiClient;
@Override
public Health health() {
try {
boolean isUp = apiClient.ping();
if (isUp) {
return Health.up()
.withDetail("api", "Available")
.withDetail("responseTime", "50ms")
.build();
}
return Health.down()
.withDetail("api", "Unavailable")
.build();
} catch (Exception e) {
return Health.down(e).build();
}
}
}
Pregunta 6: ¿Cómo añadir información a /actuator/info?
Respuesta:
# application.yml
info:
app:
name: Mi Aplicación
version: 1.0.0
description: API REST
contact:
email: support@example.com
O con un InfoContributor:
@Component
public class CustomInfoContributor implements InfoContributor {
@Override
public void contribute(Info.Builder builder) {
builder.withDetail("uptime", getUptime());
builder.withDetail("activeUsers", getActiveUsers());
}
}
Pregunta 7: ¿Cómo asegurar los endpoints de Actuator?
Respuesta:
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
http.securityMatcher("/actuator/**")
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health").permitAll()
.requestMatchers("/actuator/**").hasRole("ADMIN")
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
Pregunta 8: ¿Cómo cambiar la ruta base de Actuator?
Respuesta:
management:
endpoints:
web:
base-path: /manage # /manage/health en lugar de /actuator/health
Pregunta 9: ¿Cómo deshabilitar un endpoint específico?
Respuesta:
management:
endpoint:
env:
enabled: false
beans:
enabled: false
Pregunta 10: ¿Cómo exponer Actuator en un puerto diferente?
Respuesta:
management:
server:
port: 9090 # Actuator en el puerto 9090
address: 127.0.0.1 # Accesible solo localmente
Pregunta 11: ¿Cómo modificar los niveles de log en caliente?
Respuesta:
# Ver los loggers
curl http://localhost:8080/actuator/loggers
# Cambiar un nivel
curl -X POST http://localhost:8080/actuator/loggers/com.example \
-H "Content-Type: application/json" \
-d '{"configuredLevel": "DEBUG"}'
Pregunta 12: ¿Cómo obtener un thread dump?
Respuesta:
curl http://localhost:8080/actuator/threaddump
Útil para diagnosticar:
- Deadlocks
- Hilos bloqueados
- Problemas de rendimiento
Pregunta 13: ¿Cómo obtener un heap dump?
Respuesta:
curl -o heapdump.hprof http://localhost:8080/actuator/heapdump
Analizar con:
- Eclipse MAT
- VisualVM
- JProfiler
Pregunta 14: ¿Qué es el endpoint /actuator/env?
Respuesta: Muestra todas las propiedades de entorno:
- Variables del sistema
- Variables de entorno
- Propiedades de application.yml
- Perfiles activos
curl http://localhost:8080/actuator/env/spring.datasource.url
Atención: ¡puede exponer secretos!
Pregunta 15: ¿Cómo ocultar las propiedades sensibles?
Respuesta:
management:
endpoint:
env:
keys-to-sanitize:
- password
- secret
- key
- token
- credential
Los valores se reemplazan por ******.
Preguntas 16-30: Métricas y Monitoreo
Pregunta 16: ¿Qué es Micrometer?
Respuesta: Micrometer es una fachada de métricas (como SLF4J para el logging) que permite publicar métricas en diferentes sistemas:
- Prometheus
- Datadog
- InfluxDB
- CloudWatch
Spring Boot Actuator lo utiliza por defecto.
Pregunta 17: ¿Cómo acceder a las métricas?
Respuesta:
# Lista de métricas
curl http://localhost:8080/actuator/metrics
# Métrica específica
curl http://localhost:8080/actuator/metrics/jvm.memory.used
# Con tags
curl http://localhost:8080/actuator/metrics/http.server.requests?tag=uri:/api/users
Pregunta 18: ¿Qué métricas están disponibles por defecto?
Respuesta:
| Categoría | Ejemplos |
|---|---|
| JVM | jvm.memory.used, jvm.gc.pause |
| HTTP | http.server.requests |
| Tomcat | tomcat.sessions.active |
| DataSource | hikaricp.connections.active |
| Cache | cache.gets, cache.puts |
| Sistema | system.cpu.usage, disk.free |
Pregunta 19: ¿Cómo crear una métrica personalizada Counter?
Respuesta:
@Service
public class OrderService {
private final Counter ordersCounter;
public OrderService(MeterRegistry registry) {
this.ordersCounter = Counter.builder("orders.created")
.description("Number of orders created")
.tag("type", "online")
.register(registry);
}
public Order createOrder(OrderRequest request) {
Order order = processOrder(request);
ordersCounter.increment();
return order;
}
}
Pregunta 20: ¿Cómo crear una métrica Timer?
Respuesta:
@Service
public class PaymentService {
private final Timer paymentTimer;
public PaymentService(MeterRegistry registry) {
this.paymentTimer = Timer.builder("payment.processing")
.description("Payment processing time")
.register(registry);
}
public Payment process(PaymentRequest request) {
return paymentTimer.record(() -> {
// Tratamiento
return doProcess(request);
});
}
}
Pregunta 21: ¿Cómo crear una métrica Gauge?
Respuesta:
@Component
public class QueueMetrics {
private final BlockingQueue<Task> queue;
public QueueMetrics(MeterRegistry registry, BlockingQueue<Task> queue) {
this.queue = queue;
Gauge.builder("queue.size", queue, BlockingQueue::size)
.description("Current queue size")
.register(registry);
}
}
Pregunta 22: ¿Cómo usar @Timed para medir métodos?
Respuesta:
@Configuration
public class MetricsConfig {
@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
@Service
public class UserService {
@Timed(value = "user.find", description = "Time to find user")
public User findById(Long id) {
return userRepository.findById(id).orElseThrow();
}
}
Pregunta 23: ¿Cómo configurar Prometheus?
Respuesta:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
management:
endpoints:
web:
exposure:
include: prometheus
Acceso: /actuator/prometheus
Pregunta 24: ¿Cómo configurar Prometheus para scrapear las métricas?
Respuesta:
# prometheus.yml
scrape_configs:
- job_name: 'spring-boot'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app:8080']
Pregunta 25: ¿Cómo visualizar las métricas en Grafana?
Respuesta:
- Configurar Prometheus como fuente de datos
- Importar un dashboard de Spring Boot (ID: 12900)
- O crear paneles personalizados:
# Solicitudes HTTP por segundo
rate(http_server_requests_seconds_count[5m])
# Tiempo de respuesta promedio
rate(http_server_requests_seconds_sum[5m]) / rate(http_server_requests_seconds_count[5m])
# Uso de memoria
jvm_memory_used_bytes{area="heap"}
Pregunta 26: ¿Cómo añadir tags globales a las métricas?
Respuesta:
@Configuration
public class MetricsConfig {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config()
.commonTags("application", "my-app")
.commonTags("environment", "production");
}
}
Pregunta 27: ¿Cómo medir el tiempo de arranque?
Respuesta:
@Component
public class StartupMetrics implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
long startupTime = System.currentTimeMillis()
- event.getTimestamp().toEpochMilli();
log.info("Application started in {} ms", startupTime);
}
}
También disponible vía Actuator: /actuator/startup
Pregunta 28: ¿Cómo implementar alertas sobre las métricas?
Respuesta: En Prometheus/Alertmanager:
# alerts.yml
groups:
- name: spring-boot
rules:
- alert: HighErrorRate
expr: rate(http_server_requests_seconds_count{status="500"}[5m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate detected"
Pregunta 29: ¿Cómo monitorear las conexiones a la base de datos?
Respuesta: Métricas automáticas de HikariCP:
# Conexiones activas
curl .../actuator/metrics/hikaricp.connections.active
# Conexiones en espera
curl .../actuator/metrics/hikaricp.connections.pending
# Tiempo de adquisición
curl .../actuator/metrics/hikaricp.connections.acquire
Pregunta 30: ¿Cuáles son las buenas prácticas de monitoreo?
Respuesta:
- Monitorear las 4 señales clave (RED): Rate, Errors, Duration
- Configurar alertas relevantes
- Utilizar dashboards
- Centralizar logs y métricas
- Monitorear las dependencias (DB, cache, APIs externas)
- Health checks para el balanceador de carga
- Trazas distribuidas para microservicios
- Automatizar los runbooks
Puntuación
| Puntuación | Nivel |
|---|---|
| 27-30 | Excelente - Actuator dominado |
| 21-26 | Bien - Algunas revisiones |
| 15-20 | Medio - Repase los capítulos |
| Menos de 15 | A revisar |