在登录vertx的多个模块时,基本要求我们应该能够为单个请求关联所有日志。
由于vertx是异步的,因此保留logid,conversationid,eventid的最佳位置。
我们可以实施的任何解决方案或模式?
答案 0 :(得分:4)
在基于线程的系统中,当前线程保持当前上下文,因此MDC或任何ThreadLocal都会这样做。
在基于actor的系统(如Vertx)中,您的上下文就是消息,因此您必须为发送的每条消息添加相关ID。
对于任何处理程序/回调,您必须将其作为方法参数传递或引用最终方法变量。
要通过事件总线发送消息,您可以将有效负载包装在JsonObject中,并将相关ID添加到包装器对象
vertx.eventBus().send("someAddr",
new JsonObject().put("correlationId", "someId")
.put("payload", yourPayload));
或者您可以使用DeliveryOption
//send
vertx.eventBus().send("someAddr", "someMsg",
new DeliveryOptions().addHeader("correlationId", "someId"));
//receive
vertx.eventBus().consumer("someAddr", msg -> {
String correlationId = msg.headers().get("correlationId");
...
});
还有更复杂的选项,例如在事件总线上使用Interceptor,Emanuel Idi用它来实现Vert.x的Zipkin支持,https://github.com/emmanuelidi/vertx-zipkin,但我不确定当前这种整合的现状。
答案 1 :(得分:1)
如果多个模块意味着在同一个Vertx实例上运行多个Verticle,您应该能够使用普通的日志库,如SLF4J,Log4J,JUL等。然后您可以将日志保存在您选择的目录中,例如 local.HomePage = instance.Widget.extend({
start: function() {
this.$el.append("<div>Hello dear Odoo user!</div>");
var greeting = new local.GreetingsWidget(this);
return greeting.appendTo(this.$el);
},
});
。
但是,如果您的意思是如何关联多个Vertx实例之间的日志,那么我建议您查看GrayLog或类似的应用程序以进行分布式/集中式日志记录。如果您为每个请求使用唯一ID,则可以传递它并在日志中使用它。或者,根据您的授权系统,如果您根据请求使用唯一令牌,则可以记录这些令牌。集中式日志记录系统可用于根据该信息聚合和过滤日志。
答案 2 :(得分:1)
关于此问题的简单答案令人惊讶地缺乏,考虑到它的简单性,这很奇怪。
假设您在收到请求或消息时在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();
});
答案 3 :(得分:0)
使用vertx-sync
和ThreadLocal
作为关联ID。 (即“ FiberLocal”)。对我来说很棒。