Spring Boot 4.1 + OpenTelemetry : le guide complet pour une observabilité sans douleur
Temps de lecture : ~10 min
Niveau : Intermédiaire / Senior
Stack : Spring Boot 4.1, OpenTelemetry, Grafana LGTM (Loki · Grafana · Tempo · Mimir)
Pendant des années, "ajouter de l'observabilité" à un projet Spring Boot, c'était un chantier à part entière. Entre l'agent OpenTelemetry qui casse à chaque upgrade de JVM, les cinq dépendances Micrometer à synchroniser, et le choix douloureux entre Zipkin, Jaeger et "quelque chose de compatible avec notre infra" — la friction était réelle.
Spring Boot 4.1 règle ça proprement. Dans cet article, je vous montre comment brancher traces + métriques + logs en production avec une seule dépendance, et pourquoi ça change concrètement la vie d'une équipe.
Pourquoi l'observabilité est non-négociable en 2026
L'observabilité repose sur trois piliers :
- Traces : le chemin complet d'une requête, de l'entrée HTTP jusqu'à la base de données
- Métriques : des mesures agrégées dans le temps (latence p99, taux d'erreur, mémoire JVM)
- Logs : les événements textuels — mais corrélés aux traces pour qu'ils soient utiles
Sans ces trois piliers, vous êtes aveugles en production. L'espoir n'est pas une stratégie de production.
Avant Spring Boot 4 : le parcours du combattant
Trois approches existaient, toutes imparfaites :
1. L'agent OpenTelemetry Java — Zéro modification de code, mais des conflits de versions à chaque upgrade JVM.
2. Un starter OpenTelemetry tiers — Librairies en version alpha, dépendances transitives instables.
3. Spring Boot Actuator + Micrometer + Zipkin — Fonctionne, mais vous tire dans tout l'écosystème Actuator pour brancher de simples traces.
La solution Spring Boot 4.1 : une dépendance, trois piliers
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-opentelemetry</artifactId>
</dependency>
Ce starter embarque l'API OpenTelemetry, le bridge Micrometer, et les exporters OTLP pour métriques et traces. Il utilise OTLP (OpenTelemetry Protocol), le standard ouvert du marché : compatible Grafana, Datadog, Honeycomb, Jaeger — le code applicatif ne change pas selon le backend.
Setup complet avec la stack LGTM
| Outil | Rôle |
|---|---|
| Loki | Stockage des logs |
| Grafana | Visualisation unifiée |
| Tempo | Stockage des traces |
| Mimir | Stockage des métriques (compatible Prometheus) |
Sur start.spring.io, créez un projet avec Spring Boot 4.1.x, Spring Web, OpenTelemetry et Docker Compose Support. Le conteneur LGTM démarre automatiquement.
Configuration minimale
spring:
application:
name: mon-service
management:
tracing:
sampling:
probability: 1.0 # 100% en dev, 0.1 en prod
otlp:
metrics:
export:
url: http://localhost:4318/v1/metrics
opentelemetry:
tracing:
export:
otlp:
endpoint: http://localhost:4318/v1/traces
logging:
export:
otlp:
endpoint: http://localhost:4318/v1/logs
Spring Boot 4.1.0-RC1 ajoute le support des variables d'environnement OTLP SDK — finis les configs hardcodées, tout passe par l'env (idéal CI/CD et Kubernetes) :
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer ${TOKEN}
Ce que vous obtenez sans écrire une ligne de code
L'instrumentation automatique couvre :
- Requêtes HTTP entrantes (
@RestController) - Appels HTTP sortants (
RestTemplate,RestClient,WebClient) - Requêtes JDBC
- Injection du
traceIddans tous les logs
2026-05-31T10:42:11.801 INFO [mon-service,4a3f8c2d1b6e9a7f,2d1b6e9a7f4a3f8c] c.v.MonController : Traitement commande #42
Ce traceId permet de sauter directement du log au trace complet dans Grafana.
Métriques custom
@Observed (simple)
@Observed(name = "commande.traitement")
@PostMapping("/commandes")
public ResponseEntity<Commande> creerCommande(@RequestBody CommandeRequest req) {
// Spring génère un span + une métrique timer automatiquement
}
ObservationRegistry (contrôle total)
@Service
public class PrixService {
private final ObservationRegistry registry;
<span class="hljs-keyword">public</span> BigDecimal <span class="hljs-title function_">calculerPrix</span><span class="hljs-params">(Produit produit)</span> {
<span class="hljs-keyword">return</span> Observation.createNotStarted(<span class="hljs-string">"prix.calcul"</span>, registry)
.lowCardinalityKeyValue(<span class="hljs-string">"categorie"</span>, produit.getCategorie())
.observe(() -> doCalculerPrix(produit));
}
}
Exporter les logs vers Loki
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-logback-appender-1.0</artifactId>
<version>2.21.0-alpha</version>
</dependency>
<!-- logback-spring.xml -->
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="OTEL"
class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="OTEL"/>
</root>
</configuration>
@Component
class OpenTelemetryLogbackWiring implements InitializingBean {
private final OpenTelemetry openTelemetry;
OpenTelemetryLogbackWiring(OpenTelemetry openTelemetry) {
<span class="hljs-built_in">this</span>.openTelemetry = openTelemetry;
}
<span class="hljs-meta">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">afterPropertiesSet</span><span class="hljs-params">()</span> {
OpenTelemetryAppender.install(<span class="hljs-built_in">this</span>.openTelemetry);
}
}
Résultat : dans Grafana, cliquez sur un log Loki → "View Trace in Tempo" → trace complet de la requête.
Retour terrain Tech Lead
Après migration de deux projets Spring Boot 3 → 4 :
Ce qui a changé pour l'équipe :
- Visibilité prod dès le jour 1 pour les nouveaux devs
- Debug perf : "grep les logs 30 min" → "ouvre Grafana et suis le trace"
- Attention :
sampling.probabilityà0.1sur 500 req/s génère ~4 Go de traces/jour — dimensionnez Tempo en conséquence
Actuator vs OpenTelemetry Starter — ils ne sont pas concurrents. Sur Kubernetes, j'utilise les deux :
- OTel Starter → traces, métriques, logs via OTLP
- Actuator → health probes K8s +
/actuator/info
Gotcha : le traceId dans Loki nécessite le logback-spring.xml custom ci-dessus. Avec la config par défaut, il apparaît en console mais pas dans Loki.
Checklist production
-
sampling.probabilityadapté au volume (0.05–0.2) - Variables d'environnement OTLP par env (dev/staging/prod)
- Retention Tempo configurée (défaut 24h — insuffisant)
- Alertes Grafana sur
http_server_requests_seconds{quantile="0.99"} -
spring.application.namedéfini - Actuator conservé pour les health probes K8s
Conclusion
Le spring-boot-starter-opentelemetry est l'une des meilleures additions de Spring Boot 4 : observabilité complète, standard ouvert, zéro vendor lock-in. Pour tout nouveau projet, c'est mon choix par défaut dès le jour 1.
Le code de démo est disponible sur github.com/danvega/ot.
Sources :