Thread name filter
You can use a filter to set the name of a thread as it handles a request. Useful things to put in the thread name are the name of the user, a token to identify the request and any other useful objects in the session, such as a selected purchase order.
Here's the code for the filter. You will need to adapt it to your code:
package com.---.filter; import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; import com.---.domain.User; public class ThreadNameFilter implements Filter { /** * Log. */ private static Logger LOGGER = Logger.getLogger("com.---.filter.ThreadNameFilter"); private static long requestToken = 0; // Just a number to tie the logs for one request together. private static final int jvm = (int)(Math.random() * 10000); // If multiple JVMs per box, so this should allow us to differentiate between sessions in the 2 JVMs. private FilterConfig filterConfig; public void init(FilterConfig filterConfig) throws ServletException { LOGGER.debug("init()"); this.filterConfig = filterConfig; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest theRequest = (HttpServletRequest)request; HttpSession session = theRequest.getSession(false); String oldThreadName = Thread.currentThread().getName(); try { try { // Change the thread name to add useful info. StringBuffer sb = new StringBuffer(); if(session != null) { User user = (User)session.getAttribute(User.NAME); if(user == null) { sb.append("User[No user object]"); } else { sb.append("UserID["); sb.append(user.getId()); sb.append("] userName["); sb.append(user.getUserName()); sb.append("] screenName["); sb.append(user.getScreenName()); sb.append("] "); } } sb.append("JVM["); sb.append(jvm); sb.append("] RT["); synchronized(ThreadNameFilter.class) { requestToken++; sb.append(requestToken); } sb.append("]"); // Add useful things from the session e.g. selected PO number. Thread.currentThread().setName(sb.toString()); } finally { chain.doFilter(request, response); } } finally { // Reset the thread name to avoid confusion. Thread.currentThread().setName(oldThreadName); } } /** * */ public void destroy() { } }
Add this to web.xml:
<!-- Filter to set the thread name. --> <filter> <filter-name>threadNameFilter</filter-name> <filter-class>com.---.filter.ThreadNameFilter</filter-class> </filter> ... <filter-mapping> <filter-name>threadNameFilter</filter-name> <url-pattern>*</url-pattern> </filter-mapping>
The request token (RT) just displays a single number which is the same for all logs from one request, so you can tie a single request together. You could add a session token to tie all the logs from one session togehter.