Propagating & Managing TraceID across multiple events in Kafka

58 Views Asked by At

I'm working on a Spring Cloud Stream application where messages are produced to a Kafka topic and then consumed by another service. I'm aiming to propagate the TraceID across the complete flow for distributed tracing purposes.

The first approach that came to my mind was to generate some traceID for the producer and pass it along with the message via headers. Then, while consuming that message, I thought to use the traceID sent along with the header to generate a new span.

I was planning to do this, but could not figure out how can it be done.

Here is the code that I wrote for the same: 

import io.micrometer.tracing.Tracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;


import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Supplier;


@SpringBootApplication
public class TracingApplication {
   Logger log= LoggerFactory.getLogger(TracingApplication.class);


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


   // Producer
   @Bean
   public Supplier<Message<String>> supplierBinding1(Tracer tracer) {
      return () -> {
         try {
            Thread.sleep(1500);
         }
         catch (InterruptedException e){
            throw new RuntimeException(e);
         }

         // Assume the random ID generated as the TraceID & SpanID
         String traceID= UUID.randomUUID().toString();
         String spanID= UUID.randomUUID().toString();


         String msg= "Hello";


         log.info("Sending message: "+ msg+"    traceID: "+ traceID+"  spanID: "+ spanID);


         Message<String> myMsg= MessageBuilder.withPayload(msg)
               .setHeader("traceID", traceID)
               .setHeader("spanID", spanID).build();
         return myMsg;
      };
   }


   // Consumer
   @Bean public Consumer<Message<String>> consumerBinding1(Tracer tracer) {
      return myMsg -> {
         String traceID= (String) myMsg.getHeaders().get("traceID");
         String spanID= (String) myMsg.getHeaders().get("spanID");


         String msg= myMsg.getPayload();

         // Generate a new span here via using the traceID received from the producer
         log.info("Message received: "+ msg+"   traceID: "+ traceID+"  spanID: "+ spanID);
      };
   }
}

Here is my application.yml file:

spring:
  application:
    name: "tracing"
  cloud:
    function:
      definition: consumerBinding1;supplierBinding1
    stream:
      bindings:
        supplierBinding1-out-0:
          destination: supplier1-topic

        consumerBinding1-in-0:
          destination: supplier1-topic

I am aware that the TraceID should be same for both Producer & Consumer, but spanID for both of them should be different, but how do I achieve this.

What's the most recommended approach to propagate the TraceID from one event to the other in Kafka & how do I effectively manage these IDs (TraceID and SpanID)?

Additional Information of my project:

• Spring Boot version: 3.2.3

• Java Version: 17

• Using Gradle as the dependency management tool

I want to achieve consistent TraceID propagation throughout the complete flow, enabling comprehensive tracing and analysis of data processing across my microservices.
How should I do it? Any help is appreciated. Thanks in advanced!

0

There are 0 best solutions below