使用Java中的reactor模式透明地记录关联/请求id

时间:2016-04-29 09:29:00

标签: java logging log4j slf4j reactor

问题由两部分组成

  1. 此ID的正确命名是什么。我在互联网上看到不同的名字:相关ID,请求ID,交易ID。 我将举一个例子来更好地描述我所说的内容,而我希望它是非常常见和明显的案例。
  2. 我希望操作的每个日志都附带唯一的id,以便能够使用此id grep日志并查看与操作有关的每个语句。

    class Controller {
      void process(Request request) {
        log.debug("{} Request accepted {}", id, request)
        Result result = service.process(request.data())
        log.debug("{} Request ended with {}", id, result)
      }
    }
    
    class Service {
      void process(Data data) {
        log.debug("{} Service started processing data {}", id, data);
        Result resultOne = repoOne.modify(data);
        log.debug("{} Repo one returned {}", id, resultOne);
        Result resultTwo = repoTwo.modify(data);
        log.debug("{} Repo two returned {}", id, resultTwo);
        return combinedResult(resultOne, resultTwo);
      }
    }
    

    预期的日志是在整个过程中具有相同的唯一ID

    ABCDE-ID Request accepted WITH DATA
    ABCDE-ID Service started processing DATA
    ABCDE-ID Repo one returned SUCCESS
    ABCDE-ID Repo two returned FAILURE
    ABCDE-ID Request ended with FAILURE
    
    1. 如果应用程序使用reactor模式,如何在java中的代码上透明地注入此id?
    2. 在每个请求的线程模型中,可以使用log4j框架中的MDC实现此目的。在rector模式中,在等待io操作的同时,同一个线程同时执行不同的请求,因此线程局部变量将无济于事。

      直接的解决方案是将id添加到每个方法作为参数,但这看起来很难看。我正在寻找另一种解决方案。

1 个答案:

答案 0 :(得分:0)

如果您可以确保在同一thread内执行调用链,则可以使用ThreadLocal存储您的相关性id

实际上 Log4J MDC(映射诊断上下文)功能,允许您实现开箱即用。