views:

446

answers:

1

Hi!

I am developing a Java EE web application that is run under JBoss.

I want to do the following: When a user sends an http request (by opening a page or through AJAX) all the logs that are related to this request are collected and then saved into the database. By related I mean that they are being logged during the process of handling the current request. Tha hardest part is collecting the logs related to a single request.

I was looking into this solution:

JBoss uses log4j for logging. When the app starts, a start listener registers a log4j appender that collects all the logs into a ThreadLocal field. In the end of the request handling the logs are taken from the field and saved into the DB.

But, it seems now, that log4j appenders work in other threads. This makes this solution imposible.

Do you have any idea, how this could be made?

Thanks, Artem B.

+4  A: 

You can use the log4j MDC class (Mapped Diagnostic Context) to associate certain data with the current thread.

I use this often to add the Session ID to the log output for whatever logging is going in for that session:

public class AddSessionIdToLogFilter implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,
            ServletException {

            if (request instanceof HttpServletRequest) {
                HttpServletRequest httpRequest = (HttpServletRequest) request;
                String sessionID = httpRequest.getSession().getId();

                MDC.put("SessionID", sessionID);
            }   

            ...

Then you just refer to the MDC by key in your PatternLayout. Not sure how the DB appender works, but I assume it can log MDC fields too...

log4j.appender.LOGFILE.layout.ConversionPattern= ... [SessionID=%X{SessionID}] ...
matt b
I'll try that soon and will tell if it works out. Thanks!
artemb