了解Spring Webflux的日志记录

679 阅读2分钟

概述

Spring WebFlux中的DEBUG级别的日志是紧凑的、最小的,并且对人友好。它专注于高价值的信息,这些信息可以反复使用,而其他信息只有在调试某个特定问题时才适用。

TRACE级别的日志通常遵循与DEBUG相同的原则(例如,也不应该是一个防火墙),但可用于调试任何问题。此外,一些日志信息在TRACE与DEBUG下可能会显示不同的细节水平。

长标识

在WebFlux中,一个请求可以在多个线程中运行,线程ID对于关联属于特定请求的日志消息没有用。这就是为什么WebFlux的日志信息默认以一个特定请求的ID作为前缀。

在服务器端,日志ID存储在ServerWebExchange属性(LOG_ID_ATTRIBUTE)中,而基于该ID的格式化前缀可通过ServerWebExchange#getLogPrefix()获得。在WebClient端,日志ID存储在ClientRequest属性(LOG_ID_ATTRIBUTE)中,而一个完全格式化的前缀可以从ClientRequest#logPrefix()中获得。

敏感数据

DEBUG和TRACE日志可以记录敏感信息。这就是为什么表单参数和头文件默认是屏蔽的 ,你必须明确地完全启用它们的日志记录。下面的例子显示了如何对服务器端的请求这样做。

Java

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

Kotli

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

下面的例子展示了如何对客户端的请求进行记录。

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

SLF4J和Log4J 2等日志库提供了避免阻塞的异步日志器。虽然这些都有自己的缺点,比如可能会丢弃无法排队记录的消息,但它们是目前在反应式、非阻塞式应用中使用的最佳可用选项。

自定义编解码器

应用程序可以注册自定义编解码器,以支持额外的媒体类型,或默认编解码器不支持的特定行为。

开发者所表达的一些配置选项在默认编解码器上是强制执行的。自定义编解码器可能希望有机会与这些偏好保持一致,如强制执行缓冲限制或记录敏感数据。

下面的例子显示了如何对客户端的请求这样做。

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()

结语

总之,在这篇博客中,我们已经了解了Spring Webflux的日志记录。