Logging in Spring WebFlux

Visualizing data - blue matrix with data, electronic, digital, abstract, dark blue, data science
Reading Time: 2 minutes

Overview:

DEBUG level logging in Spring WebFlux is compact, minimal, and human-friendly. It
focuses on high-value bits of information that are useful over and over again vs others that are
applicable only when debugging a specific issue.

TRACE level logging generally follows the same principles as DEBUG (and for example also should not
be a firehose) but can be used for debugging any issue. In addition, some log messages may show a
different level of detail at TRACE vs DEBUG.

Long Id:

In WebFlux, a single request can be run over multiple threads and the thread ID is not useful for
correlating log messages that belong to a specific request. This is why WebFlux log messages are
prefixed with a request-specific ID by default.

On the server side, the log ID is stored in the ServerWebExchange attribute (LOG_ID_ATTRIBUTE), while a
fully formatted prefix based on that ID is available from ServerWebExchange#getLogPrefix(). On the
WebClient side, the log ID is stored in the ClientRequest attribute (LOG_ID_ATTRIBUTE) ,while a fully
formatted prefix is available from ClientRequest#logPrefix().

Sensitive Data:

DEBUG and TRACE logging can log sensitive information. This is why form parameters and headers are
masked by default and you must explicitly enable their logging in full.

The following example shows how to do so for server-side requests:

Java:

@Configuration
@EnableWebFlux
class MyConfig implements WebFluxConfigurer {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().enableLoggingRequestDetails(true);
}
}

Kotlin:

@Configuration
@EnableWebFlux
class MyConfig : WebFluxConfigurer {
override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
configurer.defaultCodecs().enableLoggingRequestDetails(true)
}
}

The following example shows how to do so for client-side requests:

Java:

Consumer consumer = configurer ->
configurer.defaultCodecs().enableLoggingRequestDetails(true);
WebClient webClient = WebClient.builder()
.exchangeStrategies(strategies -> strategies.codecs(consumer))
.build();

Kotlin:

val consumer: (ClientCodecConfigurer) -> Unit = { configurer ->
configurer.defaultCodecs().enableLoggingRequestDetails(true) }
val webClient = WebClient.builder()
.exchangeStrategies({ strategies -> strategies.codecs(consumer) })
.build()

Appenders:

Logging libraries such as SLF4J and Log4J 2 provide asynchronous loggers that avoid blocking.
While those have their own drawbacks such as potentially dropping messages that could not be
queued for logging, they are the best available options currently for use in a reactive, non-blocking
application.

Custom Codecs:

Applications can register custom codecs for supporting additional media types, or specific
behaviors that are not supported by the default codecs.

Some configuration options expressed by developers are enforced on default codecs. Custom codecs
might want to get a chance to align with those preferences, like enforcing buffering limits or
logging sensitive data.

The following example shows how to do so for client-side requests:

Java:

WebClient webClient = WebClient.builder()
.codecs(configurer -> {
CustomDecoder decoder = new CustomDecoder();
configurer.customCodecs().registerWithDefaultConfig(decoder);
})
.build();

Kotlin:

val webClient = WebClient.builder()
.codecs({ configurer ->
val decoder = CustomDecoder()
configurer.customCodecs().registerWithDefaultConfig(decoder)
})
.build()

Conclusion:

In conclusion, in this blog, we have learned about logging in Spring Webflux. I will be covering more topics on spring webflux in my future blogs, stay connected. Happy learning 🙂

For more, you can refer to the webflux documentation: https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html

For a more technical blog, you can refer to the Knoldus blog: https://blog.knoldus.com/

Written by 

Hello! Currently, I am Software Consultant at Knoldus Inc. I have completed my B.Tech from Abdul Kalam Technical University. Right now I am focusing on JAVA Frameworks. Apart from that my hobbies are playing guitar and listening to music.