映射内带有 MDC 上下文的 Reactor 日志
在我的 Spring Webflux 应用程序中,为了在日志(MDC)中包含跟踪标头,我遵循了 Reactor 的常见问题解答(https://projectreactor.io/docs/core/release/reference/#faq.mdc)。效果很好。但是,当我需要添加具有同步处理的日志(例如在地图内)时,它不适合。
为了解决这个问题,我为 slf4j Logger 创建了一个装饰器,它将 ContextView:
public class LoggerWithMDC {
private final Logger logger;
public void info(String message, ContextView context, Object... args) {
logWithTracingHeaders(context, () -> logger.info(message, args));
}
private static void logWithTracingHeaders(ContextView context, Runnable logStatement) {
final Map<String, String> mdcTracingValues = extractTracingValuesFromContext(context);
try {
mdcTracingValues.forEach(MDC::put);
logStatement.run();
} finally {
mdcTracingValues.keySet().forEach(MDC::remove);
}
}
}
和示例用法作为参数:
Mono.deferContextual(Mono::just)
.flatMap(
contextView ->
Mono.just("value")
.map(
value -> {
loggerWithMDC.info("Received value to convert: {}", contextView, value);
return value.toUpperCase();
})
.contextWrite(Context.of("traceid", ULID.random())))
它工作正常,但是有没有更好的方法可以在不传递 contextView 的情况下做到这一点?
In my Spring Webflux application to have tracing headers in the logs (MDC) I have followed the FAQ from Reactor (https://projectreactor.io/docs/core/release/reference/#faq.mdc). It works nice. However, it is not suitable when I need to add logs with synchronous processing (like within map).
To solve this problem I have created a decorator for slf4j Logger which takes as a parameter the ContextView:
public class LoggerWithMDC {
private final Logger logger;
public void info(String message, ContextView context, Object... args) {
logWithTracingHeaders(context, () -> logger.info(message, args));
}
private static void logWithTracingHeaders(ContextView context, Runnable logStatement) {
final Map<String, String> mdcTracingValues = extractTracingValuesFromContext(context);
try {
mdcTracingValues.forEach(MDC::put);
logStatement.run();
} finally {
mdcTracingValues.keySet().forEach(MDC::remove);
}
}
}
and the sample usage:
Mono.deferContextual(Mono::just)
.flatMap(
contextView ->
Mono.just("value")
.map(
value -> {
loggerWithMDC.info("Received value to convert: {}", contextView, value);
return value.toUpperCase();
})
.contextWrite(Context.of("traceid", ULID.random())))
It works fine but is there any better way to do this without passing contextView?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论