我正在使用Vaadin框架,它对拦截事件的支持很差,我不知道会话或UI何时被激活,所以我不能将它们的in放在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这样,无论有多少时间改变会话,我都会在日志中得到当前的会话。
这个是可能的吗?如何用自定义MDC实现替换logback MDC实现?我应该编辑slf4j和logback的来源吗?
发布于 2015-02-23 16:21:40
您不希望从每个日志记录行的线程局部变量中检索当前会话(这是VaadinSession.getCurrent()所做的)。API使用静态字符串类型,因为这是最快的。
Vaadin实际上有SessionInitListener和SessionDestroyListener,但这也不是您想要的: MDC是线程本地的,但不是同一个会话中的所有请求都在同一个线程中处理。因此,您必须在RequestHandler实现中的每个请求中设置MDC中的值。我不认为Vaadin在请求结束时有回调接口,因此似乎没有清除值的好地方。
UPDATE:在这个答案被接受之后,我发现实际上有一种更好的方法来设置和清除值,这样如果服务器回收不同会话的线程,它就不会包含虚假信息。您应该做的是子类VaadinServlet或VaadinPortlet,并重写createServletService(),以返回VaadinServletService或VaadinPortletService的自定义子类,然后重写requestStart()和requestEnd(),分别设置和删除MDC中的值。
https://stackoverflow.com/questions/18912907
复制相似问题