Micrometer Tracing and Spring Cloud Sleuth Compatibility

Nathan Deamer
Go City Engineering
3 min readOct 12, 2023

How to keep distributed traces working between your Spring Boot 3.x (Micrometer Tracing) and Spring Boot 2.x (Spring Cloud Sleuth).

Micrometer / Spring Cloud Sleuth

Have you started using Spring Boot 3.x? With the new Micrometer Tracing library for your distributed traces? Did you notice that your distributed traces stop when you call a service using Spring Cloud Sleuth?

Why does it happen?

Spring Cloud Sleuth and Micrometer Tracing, by default, use different tracing formats and are therefore incompatible with each other.

Spring Cloud Sleuth uses the zipkin b3 format (e.g. x-b3-TraceId)
Micrometer Tracing uses the w3c Trace Context format (e.g. traceparent=00-xxxx-xxxx-01)

When a service using the b3 format receives a request with trace headers in the w3c format (and vice versa), they are not recognised and therefore assumes it should start a new trace.

https://xkcd.com/927/

Example

I have set up 3 test services:
API Gateway: Spring Cloud Gateway, Spring Boot 3.1, Micrometer Tracing.
Spring Boot 3: Sprint Boot 3.1, Micrometer Tracing, Spring Cloud OpenFeign.
Spring Boot 2: Spring Boot 2.7, Spring Cloud Sleuth.

The API Gateway forwards a GET request to the Spring Boot 3 service, which in turn uses OpenFeign to call a GET API in the Spring Boot 2 service. With the default settings, the trace stops between Spring Boot 3 and Spring Boot 2.

api gateway → spring boot 3 → spring boot 2

Solution

Option 1

Recommended solution is to upgrade to Spring Boot 3.x. Spring provide lots of documentation on how to do this, including open rewrite recipes. And micrometer also provide a Spring Cloud Sleuth migration guide.

Option 2

If you need a “quick fix” while you’re busy upgrading to Spring Boot 3.x, you can set some Spring Cloud Sleuth properties to propagate traces in both the w3c and b3 format.

spring:
sleuth:
trace-id128: true
propagation:
type: w3c, b3
supports-join: false
  • trace-id128 — The w3c format expects trace IDs to be 128bit (32 hex characters)
  • supports-join— Spring Boot 3.x does not allow joining of spans (see screenshot)
Result from Spring Cloud Sleuth propagating both the w3c and b3 trace formats

With supports-join turned off, we get 2x spans with a different span.kind

  • server — receiver of the request
  • client — the call to the downstream service

Option 3

Not recommended, but the reverse of Option 2, force Micrometer Tracing to use the b3 propagation format and turn on span-joining-supported, which is supported by the b3 format.

The reason I don’t recommend this is that you’re forcing all your services to use the ‘old’ b3 type instead of moving onto the w3c standard that Spring themselves recommend.

management:
tracing:
propagation:
type: b3
brave:
span-joining-supported: true
Result from Micrometer Tracing propagating b3 trace format

Conclusion

Hopefully this will help out teams who are in the process of migrating their services to Spring Boot 3, but not lose any important traces that are needed for debugging issues.

--

--