views:

72

answers:

3

I have a webapplication and I want to use a different log for every user, so I can have a "history" of what the user did on the system.

This is what I have so far:

import java.io.File;
import java.io.IOException;

import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.SimpleLayout;
import org.apache.log4j.Logger;

public class LogManager {

    public Logger getLog(String username) throws IOException{
        SimpleLayout layout = new SimpleLayout(); 
        FileAppender appender = new DailyRollingFileAppender(layout, "users"+File.pathSeparator+username+File.pathSeparator+username, "'.'yyyy-MM");

        // configure the appender here, with file location, etc
        appender.activateOptions();
        Logger logger = Logger.getRootLogger();
        logger.addAppender(appender);
        return logger;
    }

}

The problem is that, as a webapplication, is multithreaded, so AFAIK I can't use RootLogger all the time and change the appenders depending on the user who I'm logging. I think I should create different Logger for each user, but is that correct?

+1  A: 

I would suggest using a log context information to record the user for any particular action, and include that in your log records.

Then whenever you need the log for a particular user, trawl through the single log file. If you need all the files split, do it when the log rotates. This post-processing will be a lot simpler than keeping an open file for every user concurrently.

Jon Skeet
This is a good approach also and I like the idea of post-processing. +1 for it. If I could accept your answer as well I would do it!
pakore
+2  A: 

The "Nested Diagnostic Context" is meant for such a use case - you can stamp each log statement with an id to identity the user (like an IP address, username, etc)

more here: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/NDC.html

(edit: here another useful post on NDC: http://stackoverflow.com/q/334367/465414 )

kartheek
+1  A: 

Try switching to logback (log4j's successor). It comes with a SiftingAppender which can be used to separate (or sift) logging according to a given runtime attribute, which would be "userid" in your case. The documentation contains an example for separating logs based on userid.

dogbane
This is exactly was I was looking for. Thanks!
pakore