← cd ~/journal
Juin 2026·v1.2·5 min·Spring BootJavaOpenTelemetryObservabilitéDevOpsGrafanaTech Lead

Spring Boot 4.1 + OpenTelemetry : le guide complet pour une observabilité sans douleur.

Avec Spring Boot 4.1, brancher traces, métriques et logs en production se résume à une seule dépendance. Voici le guide pratique complet avec la stack LGTM et le retour terrain d'un Tech Lead.

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 traceId dans 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">&quot;prix.calcul&quot;</span>, registry)
        .lowCardinalityKeyValue(<span class="hljs-string">&quot;categorie&quot;</span>, produit.getCategorie())
        .observe(() -&gt; 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.1 sur 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.probability adapté 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.name dé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 :

signed byVincent Pecquerie · @vpecquerie