Old*_*eon 5 java tomcat servlets log4j mdc
我最近发现了在记录时使用MDC的魔力.它完美地运作.
我有以下方法:
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());
}
Run Code Online (Sandbox Code Playgroud)
这被称为每个jsp中的第一个动作.这使我能够很好地跟踪日志中会话的详细信息.
但是 - 我怎么知道remove这些地图条目的时间?我应该注意哪些事件才能让我整理地图?
我在Tomcat下托管.如果它重新使用线程,那么我不会泄漏内存,因为它们本质上是线程本地的,所以每次put都会覆盖put上次使用线程时的旧内存.如果它没有 - 或者我托管在其他东西之下 - 我本质上可能永远地增长地图 - 或者至少在主机重新启动之前.
我认为我的问题的本质是 - 是否有一个我可以检测到的事件,表明特定会话或线程已完成并即将发布.
我不会将调用放在每个JSP中,而是注册一个ServletRequestListener,它会在请求开始时和完成时得到通知:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用过滤器,它可以包含通常的请求处理流程:
void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
setupMDC();
chain.doFilter(request, response);
tearDownMDC();
}
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,您只需注册相关的类,web.xml容器应该处理其余的.
| 归档时间: |
|
| 查看次数: |
2938 次 |
| 最近记录: |