我有这些用例,其中我必须从http请求标头中提取一些字段并将其设置为log4j线程本地MDC对象。为此,我已经实现了以下
import javax.servlet.ServletRequestListener;
@WebListener
public class HttpRequestEventListener implements ServletRequestListener {
private static final Logger log = org.apache.logging.log4j.LogManager
.getLogger(HttpRequestEventListener.class);
@Override
public void requestInitialized(ServletRequestEvent sre) {
if (sre.getServletRequest() instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
MDC.put("ip",request.getRemoteAddr());
MDC.put("app-name","my-awesome-app);
}
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
log.info("Final response");
}
}
如您所见,我已经在requestInitialized()方法内的线程本地MDC对象中设置了一些值,我希望该值在requestDestroyed()内的任何日志语句中仍然可用。 我放入一些sysout()来验证正在处理requestInitialized()方法的线程是否与requestDestroyed()相同,并观察其是否为同一线程。请注意,在Listener中设置的MDC值在Filter,Servlet,Spring Interceptor,Controller等中可用。它不仅在Listener的requestDestroyed()方法中可用。
请注意,我尝试使用Servlet过滤器执行相同的操作,并注意到它按预期工作。但是,我的应用程序使用一些具有许多过滤器的旧代码,并且无法控制过滤器注册的顺序。 Web请求的任何日志语句中都必须提供MDC值。所以我想到了通过WebListener来完成它,它在Filter之前执行。
我的应用程序:以Tomcat作为Web容器的Spring Boot 2应用程序
请注意,当我在本地测试监听器时,我会看到所有可用的MDC值。但是当我将其部署到Pivotal Cloud Foundry(平台即服务)时,我看不到它。
任何建议都会有所帮助。在此先感谢!