使用webflux进行上下文日志记录(标头中的相关id)



我需要一些来自控制器中协程内部标头的参数,并将它们作为请求的关联id记录。

是否可以在控制器AND中使用webflux/kotlin协同程序来使用标头中的params进行上下文日志记录?

我知道Webflux可以使用WebFilter拦截头并记录或修改它们,但它能被发送到它将触发的协同程序吗?

@RestController
class ItemController(private val itemRepository: ItemRepository) {
@GetMapping("/")
suspend fun findAllItems(): List<Item> =
// do stuff
logger.log("Corelation id is : " + myCorelationIdHeaderParam) // that's the param i need
return itemService.findAll()
}

您在webfilter中设置的任何上下文都可以通过在控制器/服务中使用subscriberContext来访问。

下面是一个使用Java的示例。您可以在Kotlin代码中使用类似的逻辑:

你的过滤器:(这里你正在设置你的"myContext"中的头值"someHeaderval"(

public class MyFilter implements WebFilter {

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String someHeaderval = request.getHeaders().get("someHeader").get(0);
return chain.filter(exchange).subscriberContext(context -> {
return context.put("myContext",someHeaderval);
});;
}
}

现在你可以在任何地方使用这个上下文:

@GetMapping(value = "/myGetApi")
public Mono<String> sampleGet() {
return Mono.subscriberContext()
.flatMap(context -> {
String myHeaderVal = (String)context.get("myContext");
//do logging with this header value
return someService.doSomething(myHeaderVal);
});
}

事实证明,您可以使用从CoroutineContext访问ReactorContext

coroutineContext[ReactorContext]

这是我的代码:

@Component
class MyWebFilter : WebFilter {
val headerKey = "correlation-token-key"
val contextKey = "correlationId"
override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
val headers: HttpHeaders = exchange.request.headers
return chain.filter(exchange)
.subscriberContext(Context.of(contextKey, headers[headerKey] ?: "unidentified"))
}
}

控制器部分(对Kotlin用户来说最重要(:

@RestController
class ItemController(private val itemRepository: ItemRepository) {
@GetMapping("/")
suspend fun findAllItems(): List<Item> =
// do stuff
logger.log("Correlation id of request is : " + coroutineContext[ReactorContext]?.context?.get<List<String>>("correlationId")?.firstOrNull()) 
return itemService.findAll()
}

最新更新