Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logback MDC on Netty or any other non-blocking IO server

Logback MDC (Mapped Diagnostic Context) is leveraging threadLocal (As far as I know) so that it will be accessible on all the log statements executed by the same thread.

My question is, will logback MDC work in the non blocking IO server-side runtime like Netty or Undertow as it used to work in for example, tomcat? If yes, how is it working as Netty/Undertow is not following one-thread-per-request unlike tomcat.

I am trying to put a traceID in MDC, so that I can trace all my log from a one transaction trail across multiple microservices/pipeline-listeners in a centralized logging system like Splunk/ELK

like image 668
so-random-dude Avatar asked Mar 04 '23 09:03

so-random-dude


2 Answers

I'm not terribly familiar with using netty directly, but I do know that it is possible to use logback MDC with asynchronous code. It isn't easy though.

Basically you need to somehow tie the traceId to the request/connection, and each time you start processing for that connection, set the traceId in the MDC for the current thread.

If you are using a thread pool, you can do this with a custom Executor that gets the current state (ex. traceId) from the current thread local storage, and creates a wrapped Runnable or Callable that sets thread local storage to the previously retrieved value before running. That wrapped runnable is then forwarded to a delegate Executor.

You can see how this is done here: https://github.com/lucidsoftware/java-thread-context/blob/master/thread-context/src/main/java/com/github/threadcontext/PropagatingExecutorService.java

In fact, depending on your needs, you may be able to use that java-thread-context project.

like image 134
Thayne Avatar answered Apr 05 '23 22:04

Thayne


As you have mentioned, the MDC implementation is based on the ThreadLocal, so it's not really applicable to the Reactor.

What I would suggest in case of Reactor (I assume you are using it by the tags) is:

  1. Using the Context (docs here) available in Mono and Flux in order to store the traceId to be available during the execution.

  2. If you're using Spring-Webflux and you want to generate the tradeId and add it to the Context in one place, then you can use the WebFilter (docs here) to do that.

  3. Then you can retrieve the data from the context using some custom helper methods, like in example by Nicolas Portman, or create your own custom logging format, where you utilize the data from the Context.
like image 23
Rozart Avatar answered Apr 05 '23 22:04

Rozart