首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Logback MDC put()可变对象

Logback MDC put()可变对象
EN

Stack Overflow用户
提问于 2013-09-20 09:10:07
回答 1查看 1.6K关注 0票数 6

我正在使用Vaadin框架,它对拦截事件的支持很差,我不知道会话或UI何时被激活,所以我不能将它们的in放在MDC中。

通常我会:

代码语言:javascript
复制
public void onSessionBegin(){
    MDC.put("session", VaadinSession.getCurrent().toString()); //<-- String is immutable
}
public void onSessionEnd(){
    MDC.remove("session");
}

但我没有这样的活动,所以我想:

代码语言:javascript
复制
// 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的来源吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-23 16:21:40

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

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

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18912907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档