Skip to content

Spring Cloud Sleuth 3.1 Migration Guide

Marcin Grzejszczak edited this page Jan 11, 2024 · 25 revisions

High-Level Overview

We've moved the API code from Sleuth to Micrometer Tracing. The Brave and OpenTelemetry bridges have their respective modules in Micrometer Tracing.

The Autoconfiguration of Brave and OpenTelemetry Tracer got moved to Spring Boot. So did autoconfiguration for Zipkin and Wavefront reporters for both tracers.

For Spring Boot 3.0 the default Trace Id format is 128 bit and default Context Propagation format is W3C. By default we don't support joined spans (this means that when you have e.g. an HTTP span, you will no longer see the same span being there on the client and sender side, you will see two separate spans now). We also don't support multiple context propagation types.

The instrumentation code and its autoconfiguration got moved to respective projects (e.g. Web instrumentation is now in Spring Web and Spring Boot autconfigures that).

Please read the documentation with regards to the new Observation API.

Context Propagation

Since the default propagation format is w3c and in Spring Boot 3.0 we don't support multiple propagation types, you should set in your Sleuth & Boot 2.x application spring.sleuth.propagation.type=w3c,b3 so that you publish the headers in 2 formats. One for the current Boot 2.x applications (b3) and one for the new Boot 3.x applications (w3c).

Since Boot 3.0 disallows joined spans and sets trace id to be of 128 bit, set the same configuration on the Sleuth side.

  • spring.sleuth.traceId128=true
  • spring.sleuth.supportsJoin=false

Spring Cloud Sleuth API migration

The whole Spring Cloud Sleuth API module got pretty much moved to Micrometer Tracing. That means that in the vast majority of places you should just change the package from org.springframework.cloud.sleuth to io.micrometer.tracing.

Autoconfiguration

Parts of the Spring Cloud Sleuth Autoconfigure and Spring Cloud Sleuth OTel Autoconfigure modules got moved to:

Log pattern

Spring Cloud Sleuth had a TraceEnvironmentPostProcessor that would set the logging pattern that would contain trace and span ids. With Micrometer Tracing and Boot 3.0 you need to set it yourself e.g. like this

logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"

Instrumentations

You have to check each project for their Micrometer Observation configuration.

Async Instrumentation

Spring Cloud Sleuth came with a bunch of executor / executor service instrumentations (e.g. LazyTraceExecutor) that would propagate the tracing context together with a creation of a span . With the new releases of Micrometer we come to the conclusion that we have to separate those two approaches.

This is why we have the Context Propagation library that will propagate objects (thread locals) through various means of communication (you can read more about it in the Context Propagation Docs. You don't have to add Context Propagation JAR manually if you're adding Micrometer Tracing library - that will come in as a transitive dependency.

To wrap executors just use the ContextExecutorService.wrap() or ContextScheduledExecutorService.wrap() methods. You can also use ContextSnapshot.wrap() methods to wrap Runnables or Callables.

Example of setup for enabling Async Servlets and Async processing with Spring. Since this API is evolving please check the Context Propagation documentation page for the latest API examples.

@Configuration(proxyBeanMethods = false)
class CommonConfiguration {

    // Example of Async Servlets setup
    @Configuration(proxyBeanMethods = false)
    @EnableAsync
    static class AsyncConfig implements AsyncConfigurer, WebMvcConfigurer {
        @Override
        public Executor getAsyncExecutor() {
            return ContextExecutorService.wrap(Executors.newCachedThreadPool(), ContextSnapshot::captureAll);
        }

        @Override
        public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
            configurer.setTaskExecutor(new SimpleAsyncTaskExecutor(r -> new Thread(ContextSnapshotFactory.builder().build().captureAll().wrap(r))));
        }
    }


    /**
     * NAME OF THE BEAN IS IMPORTANT!
     * <p>
     * We need to wrap this for @Async related things to propagate the context.
     *
     * @see EnableAsync
     */
    // [Observability] instrumenting executors
    @Bean(name = "taskExecutor", destroyMethod = "shutdown")
    ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler() {
            @Override
            protected ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
                ExecutorService executorService = super.initializeExecutor(threadFactory, rejectedExecutionHandler);
                return ContextExecutorService.wrap(executorService, ContextSnapshot::captureAll);
            }


                @Override
                public ScheduledExecutorService getScheduledExecutor() throws IllegalStateException {
                    return ContextScheduledExecutorService.wrap(super.getScheduledExecutor());
                }
        };
        threadPoolTaskScheduler.initialize();
        return threadPoolTaskScheduler;
    }
}

Reactor

After Reactor 3.5.3

Reactor comes with a hook that automatically will setup context propagation. It's enough to call

Hooks.enableAutomaticContextPropagation();

If performance of this approach is not satisfactory, please verify whether disabling the hook and explicitly using handle or tap operators improves the performance.

Please read this section of the Micrometer docs for more information.

Before Reactor 3.5.3

We did not auto-instrument Project Reactor, you had to do that manually. Please read this section of the Micrometer docs for more information.

Testing

With Spring Cloud Sleuth, in your tests you had implementation of Tracer available in your Spring Context. With Micrometer Tracing and Boot 3.0 you need to annotate your test class with @AutoConfigureObservability to have the proper Tracer injected (otherwise it won't be available). You can read more about it here

Samples

Spring Cloud Sleuth Samples got migrated to Micrometer Samples.