Spring Boot Actuator
Monitoring, diagnostics et sondes de santé pour les applications Spring Boot en production.
Activer le starter
Ajouter dans le pom.xml :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>Sans ce starter, aucun endpoint n’est exposé — même avec une configuration manuelle.
Endpoints disponibles
Par défaut, Spring Boot expose health et info sur /actuator. Tous les autres requièrent une activation explicite.
| Endpoint | Ce qu’il retourne |
|---|---|
/actuator/health | État de santé (UP, DOWN, OUT_OF_SERVICE) |
/actuator/info | Informations libres (ex. version, description) |
/actuator/metrics | Liste des métriques disponibles |
/actuator/metrics/{nom} | Valeur d’une métrique spécifique |
/actuator/env | Propriétés de configuration résolues |
/actuator/beans | Tous les beans Spring, leur type et leur dépendance |
/actuator/conditions | Classes @Conditional — pourquoi certains beans sont ou ne sont pas créés |
/actuator/threaddump | Snapshot des threads JVM |
/actuator/loggers | Niveaux de log configurés et modifiables (Logging) |
/actuator/httptrace | Historique des requêtes HTTP (nécessite spring-boot-starter-web classique, pas WebFlux) |
/actuator/gateway/routes | Routes actives Spring Cloud Gateway (uniquement dans un projet Gateway) |
/actuator/prometheus | Format Prometheus pour Grafana/Prometheus |
Règle : n’activer que ce qui est utile.
envetbeansen production révèlent des secrets de configuration.
Configuration YAML de base
management:
endpoints:
web:
exposure:
include: health,info,metrics
base-path: /actuator
path-mapping:
health: status
endpoint:
health:
show-details: when-authorized
show-components: always
health:
liveness:
state:
enabled: true
readiness:
state:
enabled: truePourquoi path-mapping: health: status ?
Les sondes Kubernetes et Docker vérifient /status par convention. L’alias permet de garder le chemin standard Spring Boot (/actuator/health) pour le debug, tout en servant les sondes sur /actuator/status.
Voir aussi : pour les patterns de configuration
application.yml(profils, dépendances entre propriétés, validation), consulter Spring Boot — application.yml.
Sécurité — Masquer les endpoints sensibles
Sans Spring Security, tous les endpoints sont accessibles sans authentification. Dès que Spring Security est dans le classpath, les endpoints * ne sont plus publics. Pour autoriser l’accès public à certains endpoints (ex. sondes Kubernetes) et garder le reste restreint, voir aussi Authentification API pour le pattern d’authentification global du service.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@Configuration
@EnableWebSecurity
public class ActuatorSecurity {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health", "/actuator/info", "/actuator/status").permitAll()
.requestMatchers("/actuator/**").hasRole("ADMIN")
)
.csrf(csrf -> csrf.disable());
return http.build();
}
}Piège :
management.endpoints.web.exposure.include=*exposethreaddump,env,beans,loggersà quiconque connaît l’URL. En production, limiter àhealth,info,prometheus.
Endpoints personnalisés
HealthIndicator
Ajouter une dépendance à la liste UP/DOWN d’un composant externe.
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
@Component
public class BaseDeDonneesHealthIndicator implements HealthIndicator {
private final BaseDeDonneesClient client;
public BaseDeDonneesHealthIndicator(BaseDeDonneesClient client) {
this.client = client;
}
@Override
public Health health() {
try {
client.ping();
return Health.up()
.withDetail("driver", client.getDriverName())
.withDetail("latencyMs", client.getLastPingMs())
.build();
} catch (Exception e) {
return Health.down()
.withException(e)
.withDetail("reason", "Impossible de joindre la base")
.build();
}
}
}Le résultat dans /actuator/health :
{
"status": "UP",
"components": {
"db": {
"status": "UP",
"details": {
"driver": "postgresql",
"latencyMs": 3
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 53687091200,
"free": 21474836480,
"threshold": 10485760
}
}
}
}InfoContributor
Exposer des informations personnalisées dans /actuator/info :
import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;
@Component
public class InfoContributorBuild implements InfoContributor {
@Override
public void contribute(Info.Builder builder) {
builder.withDetail("build", Map.of(
"commit", System.getenv("GIT_COMMIT", "unknown"),
"version", System.getenv("APP_VERSION", "dev"),
"timestamp", System.currentTimeMillis()
));
}
}Sondes Kubernetes
Pour un déploiement Kubernetes, activer les sondes liveness et readiness :
management:
endpoint:
health:
probes:
enabled: true
health:
liveness:
state:
enabled: true
readiness:
state:
enabled: trueCela expose automatiquement :
/actuator/health/liveness— sonde de survie (k8s =/health/live)/actuator/health/readiness— sonde de prêt (k8s =/health/ready)
Attention : l’URL réelle est
/actuator/health/liveness(le préfixe/actuatorest ajouté automatiquement). Vérifier aveccurl http://localhost:8080/actuator/health/liveness.
Déclarer les sondes dans le Deployment Kubernetes
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: mon-service
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 10
periodSeconds: 5Attention : si un
path-mapping: health: statusest configuré (voir section « Configuration YAML de base »), les chemins des sondes sont aussi remappés. Adapter le Deployment Kubernetes :livenessProbe: httpGet: path: /actuator/status/liveness port: 8080 readinessProbe: httpGet: path: /actuator/status/readiness port: 8080
Intégration Prometheus + Grafana
Activer l’endpoint prometheus et exporter les métriques :
management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
export:
prometheus:
enabled: true
tags:
application: ${spring.application.name}Métriques JVM automatiques :
jvm_memory_used_bytes— mémoire utilisée par zonejvm_threads_states— threads par état (running, blocked, …)jvm_gc_pause_seconds— pauses du garbage collectorhttp_server_requests_seconds— latence des requêtes HTTPprocess_cpu_usage— utilisation CPU du processus
Pièges courants
1. Exposition inadvertée d’env en production
# ❌ MAUVAIS — `env` révèle toutes les propriétés, y compris les secrets
management:
endpoints:
web:
exposure:
include: "*"En production :
# ✅ BON — expose uniquement les endpoints non sensibles
management:
endpoints:
web:
exposure:
include: health,info,prometheus2. show-details: always révèle trop d’informations
show-details: always dans /actuator/health révèle les détails de chaque composant (taille disque, pilote de base de données, …). En production, utiliser when-authorized pour masquer les détails aux utilisateurs non-admin.
3. Endpoint httptrace absent en WebFlux
httptrace repose sur HttpTraceRepository qui n’existe pas dans un projet WebFlux. La section /actuator/httptrace renvoie alors 404. Utiliser WebHttpTraceRepository à la place, ou se tourner vers un outil externe (Prometheus) pour le tracing.
4. Annoter un HealthIndicator avec @LivenessIndicator / @ReadinessIndicator
Depuis Spring Boot 3.4, on peut préciser à quelle sonde un HealthIndicator participe :
@Component
@LivenessIndicator
public class CacheHealthIndicator implements HealthIndicator { ... }Sans annotation, un HealthIndicator participe à la fois à liveness et readiness. Cela ne peut pas servir à déclencher le shutdown — seul @PreDestroy garantit un arrêt contrôlé (déconnecter le pool JDBC, arrêter le consommateur Kafka, etc.).
5. Oublier le port management
Par défaut, Actuator partage le port HTTP de l’application (8080). Pour séparer le monitoring du trafic métier :
management:
server:
port: 8081
endpoints:
web:
base-path: /actuatorL’application écoute sur 8080, le monitoring sur 8081. Utile pour ne pas exposer /actuator au load balancer principal.
Checklist de mise en production
- Starter
spring-boot-starter-actuatorajouté management.endpoints.web.exposure.includelimité àhealth,info,prometheus- Spring Security configure l’accès :
health/infopublics, reste restreint - Sonde liveness/readiness activée (
management.endpoint.health.probes.enabled=true) - Suppression des champs sensibles (
show-details: when-authorized) - Port management distinct (
management.server.port) si souhaité - HealthIndicator personnalisée pour les dépendances externes critiques
- Monitoring Grafana/Prometheus connecté à
/actuator/prometheus