This library is a utility for adding MDC logs to a Spring Webflux application (with Spring Boot version 3).
With Maven:
<dependency>
<groupId>com.vincenzoracca</groupId>
<artifactId>spring-webflux-mdc</artifactId>
<version>1.0.2</version>
</dependency>
or with Gradle:
dependencies {
implementation 'com.vincenzoracca:spring-webflux-mdc:1.0.2'
}
In your Spring WebFlux Application:
- import the SpringMDC class in a
@Configuration
class or in the main class (@SpringBootApplication
), in this way:@Configuration @Import(SpringMDC.class) public class AppConfig { }
- add in your application.properties the headers keys and the relatives mdc keys in this way:
spring.mdc.headers.<header_key_1>=<mdc_key_1> spring.mdc.headers.<header_key_2>=<mdc_key_2>
- Optionally, if the HTTP request headers don't contain the <header_key>, the library can add the related MDC with a
UUID value. If you want me to do this, in your application.properties add this:
The spring.mdc.defaults property accepts a list of string (the header keys), with the comma as the delimiter.
spring.mdc.defaults=<header_key_1>,<header_key_2>
See the example in application.properties
If you need to add a MDC key programmatically, in the most "external" method that contains the MDC key:
- wrap the method using the wrapMDC method of MDCUtil
Example:
Original method:
@GetMapping("test-client-programmatically-2")
public Mono<ResponseEntity<MessageResponse>> getMDCProgrammaticallyExampleTwo(@RequestHeader("an-header-not-registered") String anHeader) {
log.info("[{}] Called getMDCExample with header but without MDC because it is not wrapped:", anHeader);
return Mono.just("test-another-product")
.delayElement(Duration.ofMillis(1))
.flatMap(product ->
Flux.concat(
addProduct(product, anHeader),
notifyShop(product, anHeader))
.then(Mono.just(ResponseEntity.ok(new MessageResponse("Hello World!")))));
}
With MDC:
@GetMapping("test-client-programmatically-2")
public Mono<ResponseEntity<MessageResponse>> getMDCProgrammaticallyExampleTwo(@RequestHeader("an-header-not-registered") String anHeader) {
log.info("[{}] Called getMDCExample with header but without MDC because it is not wrapped:", anHeader);
Mono<ResponseEntity<MessageResponse>> responseEntityMono = Mono.just("test-another-product")
.delayElement(Duration.ofMillis(1))
.flatMap(product ->
Flux.concat(
addProduct(product, anHeader),
notifyShop(product, anHeader))
.then(Mono.just(ResponseEntity.ok(new MessageResponse("Hello World!")))));
return MDCUtil.wrapMDC(responseEntityMono, "my-mdc-key", anHeader);
}
If you need to pass more MDC keys, you can use the wrapMDC method that accepts a Map of <mdc_key, mdc_value>.
- Run the SpringMDCApplication main class from your IDE
- Run the test-client.sh script to execute 100 HTTP calls or
make an HTTP call manually with the
localhost:8080/test-client
endpoint with theX-Amzn-Trace-Id
request header - Watch the logs in the tests.log file