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.