Problem:
I wanted to add username and ip address to each logging entry of my Java web application. I assumed I would have to go through each logging entry and add it manually, or perform some sort of fancy find/replace.
Research:
After consulting my best friend Google, I discovered that an MDC servlet filter was the correct approach. However, I wasn’t sure of how much effort was required. After some pondering I decided the correct approach is what I needed to do.
Solution:
I required a new class (see below):
package com.example;
import org.jboss.logging.MDC; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder;
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException;
public class MDCFilter implements Filter {
@Override public void init(FilterConfig filterConfig) throws ServletException { }
@Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null) { MDC.put(Constants.mdc_username, authentication.getName()); } HttpServletRequest httpRequest = (HttpServletRequest) req; String ipAddress = httpRequest.getHeader("X-FORWARDED-FOR"); if (ipAddress == null) { ipAddress = req.getRemoteAddr(); } MDC.put(Constants.mdc_ipaddress, ipAddress); try { chain.doFilter(req, resp); } finally { if (authentication != null) { MDC.remove(Constants.mdc_username); } MDC.remove(Constants.mdc_ipaddress); } }
@Override public void destroy() { }
}
Additionally, I required a modification to the web.xml:
<filter> <filter-name>mdcFilter</filter-name> <filter-class>com.example.MDCFilter</filter-class> </filter> <filter-mapping> <filter-name>mdcFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Final Thoughts:
Considering how little work was required I’m convinced I made the right decision. Also, if I need to add any additional fields to my log entries I simply need to modify the MDCFilter class. That’s it.