Logback MDC(映射诊断上下文(正在利用threadLocal(据我所知(,以便在同一线程执行的所有日志语句上都可以访问它。
我的问题是,logback MDC 是否会像 Netty 或 Undertow 那样在非阻塞 IO 服务器端运行时中工作,就像它曾经在 tomcat 中工作一样? 如果是,它是如何工作的,因为 Netty/Undertow 不像 tomcat 那样遵循每个请求一个线程。
我正在尝试在 MDC 中放置一个 traceID,以便我可以在集中式日志记录系统(如 Splunk/ELK(中跨多个微服务/管道侦听器跟踪一个事务跟踪中的所有日志
我不太熟悉直接使用 netty,但我知道可以将 logback MDC 与异步代码一起使用。不过这并不容易。
基本上,您需要以某种方式将 traceId 绑定到请求/连接,并且每次开始处理该连接时,请在 MDC 中为当前线程设置 traceId。
如果您使用的是线程池,则可以使用自定义执行器执行此操作,该执行器从当前线程本地存储中获取当前状态(例如 traceId(,并创建一个包装的 Runnable 或 Callable,用于在运行之前将线程本地存储设置为以前检索的值。然后将包装的可运行对象转发给委托执行程序。
您可以在此处查看此操作方式:https://github.com/lucidsoftware/java-thread-context/blob/master/thread-context/src/main/java/com/github/threadcontext/PropagatingExecutorService.java
实际上,根据您的需要,您可以使用该java线程上下文项目。
正如你提到的,MDC实现是基于ThreadLocal
的,所以它并不真正适用于反应器。
对于 Reactor (我假设您正在通过标签使用它(我的建议是:
-
使用
Mono
和Flux
中可用的Context
(此处的文档(来存储执行期间可用的traceId
。 -
如果您使用的是 Spring-Webflux,并且想要生成
tradeId
并将其添加到一个地方的Context
中,那么您可以使用WebFilter
(此处的文档(来执行此操作。 - 然后,您可以使用一些自定义从上下文中检索数据 帮助程序方法,例如尼古拉斯·波特曼(Nicolas Portman(的方法,或者创建自己的自定义日志记录格式,您可以在其中利用
Context
中的数据。