Netty 或任何其他非阻塞 IO 服务器上的 Logback MDC



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 (我假设您正在通过标签使用它(我的建议是:

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

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

  3. 然后,您可以使用一些自定义从上下文中检索数据 帮助程序方法,例如尼古拉斯·波特曼(Nicolas Portman(的方法,或者创建自己的自定义日志记录格式,您可以在其中利用Context中的数据。

最新更新