Skip to content

Instantly share code, notes, and snippets.

@javajack
Last active June 3, 2025 11:43
Show Gist options
  • Save javajack/752724ae9714852d29292da1dcc4a5e9 to your computer and use it in GitHub Desktop.
Save javajack/752724ae9714852d29292da1dcc4a5e9 to your computer and use it in GitHub Desktop.
Spring Boot 3 java 21 RabbitMQ Tracing End To End
spring.application.name=rabbit-tracing
server.port=8090
spring.rabbitmq.host=rabbithost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
# application.properties
logging.pattern.console=%d{HH:mm:ss.SSS} [%thread] [%X{traceId} / %X{spanId}] %-5level %logger{36} - %msg%n
logging.pattern.file=%d{HH:mm:ss.SSS} [%thread] [%X{traceId} / %X{spanId}] %-5level %logger{36} - %msg%n
management.tracing.enabled=true
spring.zipkin.enabled=false

This code sets up distributed tracing for RabbitMQ message processing in a Spring Boot application using Brave (Zipkin's Java client library). Here's what each part does:

Maven Dependencies (pom.xml)

The project includes key dependencies for tracing:

  • micrometer-tracing-bridge-brave - Bridges Micrometer tracing with Brave
  • brave-instrumentation-spring-rabbit - Provides automatic instrumentation for Spring AMQP/RabbitMQ
  • Standard Spring Boot starters for web, AMQP, and actuator

Configuration Class (RabbitTracingConfig)

The configuration class creates several beans to enable comprehensive RabbitMQ tracing:

MDC Scope Decorator

@Bean
public CurrentTraceContext.ScopeDecorator logScopeDecorator() {
    return MDCScopeDecorator.newBuilder().build();
}

This automatically injects trace and span IDs into the Mapped Diagnostic Context (MDC), making them available in log statements. Your logs will automatically include correlation IDs.

SpringRabbitTracing Bean

@Bean
public SpringRabbitTracing springRabbitTracing(Tracing tracing) {
    return SpringRabbitTracing.newBuilder(tracing)
            .remoteServiceName("rabbitmq")
            .build();
}

Creates the main tracing component that will instrument RabbitMQ operations. The remoteServiceName("rabbitmq") labels the message broker in trace visualizations.

RabbitTemplate Customizer

@Bean
public RabbitTemplateCustomizer tracingRabbitTemplateCustomizer(SpringRabbitTracing springRabbitTracing) {
    return rabbitTemplate -> springRabbitTracing.decorateRabbitTemplate(rabbitTemplate);
}

Automatically instruments the RabbitTemplate for outgoing messages. When you publish messages, this creates spans and propagates trace context.

Listener Container Factory

@Bean
public SimpleRabbitListenerContainerFactory tracingListenerContainerFactory(
        SpringRabbitTracing springRabbitTracing,
        SimpleRabbitListenerContainerFactory factory) {
    springRabbitTracing.decorateSimpleRabbitListenerContainerFactory(factory);
    return factory;
}

Instruments the listener container factory for incoming messages. This creates spans for message consumption and extracts trace context from message headers.

What This Achieves

With this configuration, you get:

  • End-to-end tracing across service boundaries via RabbitMQ
  • Automatic span creation for message publishing and consuming
  • Trace context propagation through message headers
  • Correlation IDs in logs for easier debugging
  • Service topology visualization in tools like Zipkin

When a traced request publishes a message to RabbitMQ, the trace context travels with the message, and the consuming service continues the same distributed trace, giving you complete visibility into your message-driven architecture.

<?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.5.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>co.dhan</groupId>
<artifactId>rabbit-tracing</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rabbit-tracing</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</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-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Micrometer + Zipkin bridge (if using micrometer tracing) -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/io.zipkin.brave/brave-instrumentation-spring-rabbit -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-spring-rabbit</artifactId>
<version>6.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package co.dhan.tracing;
import brave.Tracing;
import brave.context.slf4j.MDCScopeDecorator;
import brave.propagation.CurrentTraceContext;
import brave.spring.rabbit.SpringRabbitTracing;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.boot.autoconfigure.amqp.RabbitTemplateCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitTracingConfig {
@Bean
public CurrentTraceContext.ScopeDecorator logScopeDecorator() {
return MDCScopeDecorator.newBuilder().build(); // Enables MDC injection of trace/span IDs
}
@Bean
public SpringRabbitTracing springRabbitTracing(Tracing tracing) {
return SpringRabbitTracing.newBuilder(tracing)
.remoteServiceName("rabbitmq")
.build();
}
@Bean
public RabbitTemplateCustomizer tracingRabbitTemplateCustomizer(SpringRabbitTracing springRabbitTracing) {
return rabbitTemplate -> springRabbitTracing.decorateRabbitTemplate(rabbitTemplate);
}
@Bean
public SimpleRabbitListenerContainerFactory tracingListenerContainerFactory(
SpringRabbitTracing springRabbitTracing,
SimpleRabbitListenerContainerFactory factory) {
// Decorate the factory AFTER Spring Boot has auto-configured it
springRabbitTracing.decorateSimpleRabbitListenerContainerFactory(factory);
return factory;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment