4

Logback MDC(映射诊断上下文)正在利用 threadLocal(据我所知),以便在同一线程执行的所有日志语句上都可以访问它。

我的问题是,logback MDC 是否会像以前在 tomcat 中那样在 Netty 或 Undertow 等非阻塞 IO 服务器端运行时中工作?如果是,它是如何工作的,因为 Netty/Undertow 不像 tomcat 那样遵循每个请求一个线程。

我正在尝试在 MDC 中放置一个 traceID,以便我可以在像 Splunk/ELK 这样的集中式日志系统中跨多个微服务/管道侦听器的一个事务跟踪跟踪我的所有日​​志

4

2 回答 2

6

我对直接使用 netty 不是很熟悉,但我知道可以将 logback MDC 与异步代码一起使用。不过这并不容易。

基本上,您需要以某种方式将 traceId 绑定到请求/连接,并且每次开始处理该连接时,在 MDC 中为当前线程设置 traceId。

如果您使用的是线程池,则可以使用自定义 Executor 执行此操作,该 Executor 从当前线程本地存储获取当前状态(例如 traceId),并创建一个包装的 Runnable 或 Callable 将线程本地存储设置为先前检索到的值在运行之前。然后将该包装的可运行文件转发给委托执行器。

您可以在这里看到这是如何完成的:https ://github.com/lucidsoftware/java-thread-context/blob/master/thread-context/src/main/java/com/github/threadcontext/PropagatingExecutorService.java

事实上,根据您的需要,您也许可以使用那个 java-thread-context 项目。

于 2019-10-04T05:22:08.777 回答
1

正如您所提到的,MDC 实现是基于 的ThreadLocal,因此它并不真正适用于 Reactor。

如果是 Reactor(我假设您通过标签使用它),我建议的是:

  1. 使用可用的(Context 此处的文档)MonoFlux存储traceId在执行期间可用的。

  2. 如果您使用的是 Spring-Webflux 并且想要生成tradeId并将其添加到Context一个地方,那么您可以使用WebFilter (此处的文档)来执行此操作。

  3. 然后,您可以使用一些自定义辅助方法从上下文中检索数据,例如 Nicolas Portman的示例,或者创建您自己的自定义日志记录格式,在其中使用来自Context.
于 2019-10-05T12:38:15.357 回答