如何在分布式Vertx系统中关联日志事件

Kis*_*ani 5 logging distributed vert.x

在vertx的多个模块中执行日志时,基本要求是我们应该能够将单个请求的所有日志关联起来。

由于vertx是异步的,因此保留logid,conversationid和eventid的最佳位置。

我们可以实施任何解决方案或模式吗?

Cli*_*ans 6

令人惊讶的是,关于这个问题却缺乏好的答案,考虑到它是如此简单,这很奇怪。

假设您在收到请求或消息时在 MDC 上下文中设置correlationId,我发现传播它的最简单方法是使用拦截器在上下文之间传递值:

vertx.eventBus()
        .addInboundInterceptor(deliveryContext -> {
            MultiMap headers = deliveryContext.message().headers();
            if (headers.contains("correlationId")) {
                MDC.put("correlationId", headers.get("correlationId"));
                deliveryContext.next();
            }
        })
        .addOutboundInterceptor(deliveryContext -> {
            deliveryContext.message().headers().add("correlationId", MDC.get("correlationId"));
            deliveryContext.next();
        });
Run Code Online (Sandbox Code Playgroud)


Ger*_*cke 5

在基于线程的系统中,当前上下文由当前线程保存,因此MDC或任何ThreadLocal都可以。

在基于参与者的系统(例如Vertx)中,您的上下文就是消息,因此您必须在发送的每条消息中添加一个关联ID。

对于任何处理程序/回调,您都必须将其作为方法参数传递或引用最终的方法变量。

为了通过事件总线发送消息,您可以将有效负载包装在JsonObject中,然后将相关性ID添加到包装对象中

vertx.eventBus().send("someAddr", 
  new JsonObject().put("correlationId", "someId")
                  .put("payload", yourPayload));
Run Code Online (Sandbox Code Playgroud)

或者您可以使用 DeliveryOption

//send
vertx.eventBus().send("someAddr", "someMsg", 
            new DeliveryOptions().addHeader("correlationId", "someId"));

//receive    
vertx.eventBus().consumer("someAddr", msg -> {
        String correlationId = msg.headers().get("correlationId");
        ...
    });
Run Code Online (Sandbox Code Playgroud)

还有更多更复杂的选择,例如在事件总线上使用Interceptor,Emanuel Idi曾使用该拦截器来实现对Vert.x的Zipkin支持,https://github.com/emmanuelidi/vertx-zipkin,但我不确定有关此集成的当前状态。


amb*_*b85 1

如果多个模块是指在同一个 Vertx 实例上运行的多个 verticle,那么您应该能够使用普通的日志库,例如 SLF4J、Log4J、JUL 等。然后您可以将日志保存在您选择的目录中,例如/var/logs/appName.

但是,如果您的意思是如何关联 Vertx 的多个实例之间的日志,那么我建议您研究GrayLog或类似的分布式/集中式日志记录应用程序。如果您对每个请求使用唯一的 ID,则可以传递该 ID 并在日志中使用它。或者,根据您的授权系统,如果您每个请求使用唯一的令牌,您可以记录这些令牌。集中式日志记录系统可用于根据该信息聚合和过滤日志。