micrometer-metrics/micrometer-samples

SpringBoot 3 web REACTIVE application lost of all traces

Closed this issue · 4 comments

Hello Micrometer team,

Since this is my first ticket here, I would like to begin by saying thanks to those awesome samples.
They are clear, simple, and provide a very nice starting point, especially with the latest SpringBoot 3 applications.

Just wanted to reach out as I am encountering an issue related to this repo.

I took a very basic sample from this repo, it is a web (non webflux) application. I made it "minimal reproducible" with only 50 lines of code:

The pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>sk.balaz</groupId>
    <artifactId>spring-boot-logging</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-logging</name>
    <description>spring-boot-logging</description>
    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-tracing-bridge-otel</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

the applicaiton.properties

spring.application.name=Baeldung Sleuth Tutorial
management.tracing.sampling.probability=1.0
logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
debug=true
server.port=9090

the code

package sk.balaz.springbootlogging;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@SpringBootApplication
public class SpringBootLoggingApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootLoggingApplication.class, args);
    }

    private static final Logger logger = LoggerFactory.getLogger(SpringBootLoggingApplication.class);

    private static final List<Employee> DB = new ArrayList<>();
    static {
        DB.add(new Employee("1", "Frodo", "ring bearer"));
        DB.add(new Employee("2", "Bilbo", "burglar"));
    }

    @GetMapping("/api/employees")
    List<Employee> all() {
        logger.info("Look, there is a trace ID here with spring-boot-starter-web, but not with spring-boot-starter-webflux");
        return DB;
    }

    @GetMapping("/api/employees/{id}")
    Employee one(@PathVariable String id) {
        logger.info("Look, there is a trace ID here with spring-boot-starter-web, but not with spring-boot-starter-webflux" + id);
        return DB.stream() //
                .filter(employee -> employee.id().equals(id)) //
                .findFirst() //
                .orElseThrow(() -> new RuntimeException("Couldn't find " + id));
    }

    public record Employee(String id, String aaa, String bbb) {
    }
}

When running this, I can see the traces in the log. Here is a sample of the log output.

2023-01-27T13:08:06.009+08:00  INFO [Baeldung Sleuth Tutorial,,] 21840 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
2023-01-27T13:08:06.066+08:00 DEBUG [Baeldung Sleuth Tutorial,d29f0857eb656c71d92a1d26b7dd8594,1839189408df0599] 21840 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet        : GET "/api/employees", parameters={}
2023-01-27T13:08:06.074+08:00 DEBUG [Baeldung Sleuth Tutorial,d29f0857eb656c71d92a1d26b7dd8594,1839189408df0599] 21840 --- [nio-9090-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sk.balaz.springbootlogging.SpringBootLoggingApplication#all()
2023-01-27T13:08:06.086+08:00  INFO [Baeldung Sleuth Tutorial,d29f0857eb656c71d92a1d26b7dd8594,1839189408df0599] 21840 --- [nio-9090-exec-1] s.b.s.SpringBootLoggingApplication       : Look, there is a trace ID here with spring-boot-starter-web, but not with spring-boot-starter-webflux

Everything is working fine, very happy.

Now I am just going to make a 4 characters change on the pom. Just 4 characters change, no change in the application.properties, no change in the code.

Here is the log I am getting (I believe it is 100% reproducible, please give it a go with a copy paste)

2023-01-27T13:00:42.126+08:00  INFO [Baeldung Sleuth Tutorial,,] 14660 --- [ctor-http-nio-2] s.b.s.SpringBootLoggingApplication       : Look, there is a trace ID here with spring-boot-starter-web, but not with spring-boot-starter-webflux

Expectation: this migration from web to webflux would still preserve the traces.

Actual: after the migration, all traces are lost

Could you please help on this issue?

Thank you

Currently it won't work out of the box. Please read this section of the docs on how to add tracing info to mdc https://micrometer.io/docs/observation#instrumentation_of_reactive_libraries

Very clear @marcingrzejszczak and thank you for the answer.

Is it ok for me to hope, one day, this will work out of the box please?

When Spring Cloud Sleuth and Zipkin were still around, this was possible without extra code change.

We are working on that as we speak and we've made some promissing progress

Thank you!

Only if you have it handy, do you mind pasting some sort of issue tracking link, or Jira ticket?
If not, no worries, just disregard this message. Will keep my fingers crossed.