gpt4 book ai didi

java - Logback MDC put() 可变对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:21:46 26 4
gpt4 key购买 nike

我正在使用 Vaadin 框架,它对拦截事件的支持很差,我无法知道 session 或 UI 何时被激活,所以我无法将它们的 ID 放入 MDC。

通常我会:

public void onSessionBegin(){
MDC.put("session", VaadinSession.getCurrent().toString()); //<-- String is immutable
}
public void onSessionEnd(){
MDC.remove("session");
}

但是我没有这样的事件,所以我想:

// in the servlet init or wherever
MDC.put("session", new Object(){
public String toString() {
VaadinSession.getCurrent().toString()
};
}); //<-- This is mutable and will be evaluated each time

这样,无论 session 更改多少次,我都会在日志中获取当前 session 。

这可能吗?如何将 logback MDC 实现替换为自定义实现?我应该编辑 slf4j 和 logback 的源代码吗?

最佳答案

您不想从每个日志行的线程局部变量中检索当前 session (这是 VaadinSession.getCurrent() 所做的)。 API 使用静态字符串类型,因为这是最快的。

Vaadin 实际上有 SessionInitListenerSessionDestroyListener,但这也不是您想要的:MDC 是线程本地的,但并非同一 session 中的所有请求都在其中处理同一个线程。因此,您必须在 RequestHandler 的实现中针对每个请求在 MDC 中设置值。我认为Vaadin没有请求结束的回调接口(interface),所以似乎没有清除值的好地方。

更新:在这个答案被接受后,我发现实际上有一个更好的方法来设置和清除值,这样如果服务器为不同的 session 回收线程,它就不会包含虚假信息。您应该做的是 VaadinServletVaadinPortlet 的子类,并覆盖 createServletService() 以返回 VaadinServletService 的自定义子类或VaadinPortletService 依次覆盖 requestStart()requestEnd() 以分别设置和删除 MDC 中的值。

关于java - Logback MDC put() 可变对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18912907/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com