首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >何时从MDC移除

何时从MDC移除
EN

Stack Overflow用户
提问于 2014-01-15 12:21:50
回答 1查看 5.8K关注 0票数 5

我最近发现了在日志记录时使用MDCs的魔力。它工作得很完美。

我有以下方法:

代码语言:javascript
复制
public static final String MDC_CLIENT="client";
public static final String MDC_SESSION="session";
public static final String MDC_DEVICE="device";

// Called for every request.
public static void request(final HttpServletRequest request) {
  // The MDC is a thread-local storage accessable from the log formatter.
  MDC.put(MDC_CLIENT, String.format("%s:%s", request.getRemoteHost(), request.getRemotePort()));
  HttpSession session = request.getSession();
  MDC.put(MDC_SESSION, session.getId());
  MDC.put(MDC_DEVICE, (String)session.getAttribute("device"));
  // Also record the context.
  setContext(session.getServletContext());
}

这被称为每个jsp中的第一个操作。这使我能够很好地跟踪日志中会话的细节。

然而-我怎么知道什么时候remove这些地图条目?我该看什么活动才能把地图整理好呢?

我在Tomcat主持下。如果它重新使用线程,那么我就不会泄漏内存,因为它们本质上是线程本地的,因此每个put都会覆盖上一次使用线程时的旧put。如果它没有--或者我被托管在另一个不是的地方--我实际上是在永远地扩展地图--或者至少在主机重新启动之前。

我认为我的问题的本质是-是否有一个事件我可以检测到,表明一个特定的会话或线程已经完成,并即将被释放。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-15 12:43:05

与其将调用放入每个JSP中,我将注册一个ServletRequestListener,它在请求启动和完成时都会得到通知:

代码语言:javascript
复制
public class MDCListener implements ServletRequestListener {
  public void requestInitialized(ServletRequestEvent e) {
    YourUtilityClass.request((HttpServletRequest)e.getServletRequest());
  }

  public void requestDestroyed(ServletRequestEvent e) {
    YourUtilityClass.tearDown((HttpServletRequest)e.getServletRequest());
  }
}

或者,您可以使用一个筛选器,它允许您环绕通常的请求处理流程:

代码语言:javascript
复制
void doFilter(ServletRequest request, ServletResponse response,
              FilterChain chain) throws IOException, ServletException {
  setupMDC();
  chain.doFilter(request, response);
  tearDownMDC();
}

无论哪种方式,您只需在web.xml中注册相关的类,容器就应该处理其余的类。

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

https://stackoverflow.com/questions/21137307

复制
相关文章

相似问题

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