Sameek Mishra
Sameek Mishra

Reputation: 9384

how to use log4j in Multithread using java?

I want to write log for each thread using log4j and log file name will be "workthread..log",first thread print log on file "workthread-1.log" and second thread on "workthread-2.log" and so on.

class MyRunnable implements Runnable 
  {
       private Logger logger=null;

       public MyRunnable()
        {
            DOMConfigurator.configure(this.getClass().getClassLoader().getResource(LOG4J_FILEPATH));
            logger =Logger.getLogger(classname);
        }

        public void run() 
        {
          logger.info("Important job running in MyRunnable"+Thread.currentThread().getName());
        }
   }


public class TestThreads 
{
    public static void main (String [] args) 
     {
        Thread[] worker=new Thread[3];
        MyRunnable r = new MyRunnable();

        for(int i=0;i<3;i++) {
           worker[i]=new Thread(r);
           worker[i].start();
        }


    }
}//class

please help me?

Regards

Upvotes: 4

Views: 13835

Answers (5)

mezzie
mezzie

Reputation: 1296

this is how I use thread specific logger. Just copy paste and it on top of you run method and should work as is. Don't forget to change the text in caps.

String currenttime = String.valueOf(new Long(new Date().getTime()/1000));
String logFileName = "NAMEHERE_thread" + Thread.currentThread().getId() 
                     + "_" + currenttime+".log";
Logger logger = Logger.getLogger("NAMEHERE_thread" +
                                      Thread.currentThread().getId() + "_"+ currenttime);

Properties prop = new Properties();
prop.setProperty("log4j.logger.NAMEHERE_thread" + Thread.currentThread().getId() 
                 + "_" + currenttime,"DEBUG, file");

prop.setProperty("log4j.appender.file", "org.apache.log4j.RollingFileAppender");
prop.setProperty("log4j.appender.file.maxFileSize", "100MB");
prop.setProperty("log4j.appender.file.maxBackupIndex", "100");
prop.setProperty("log4j.appender.file.File", 
                 REPLACEMEWITHPATH + File.separator + logFileName);
prop.setProperty("log4j.appender.file.threshold","debug");
prop.setProperty("log4j.appender.file.layout", "org.apache.log4j.PatternLayout");
prop.setProperty("log4j.appender.file.layout.ConversionPattern", 
                 "%d [%t] %-5p [%-35F : %-25M : %-6L] %-C -%m%n");
prop.setProperty("log4j.appender.stdout", "org.apache.log4j.ConsoleAppender");
PropertyConfigurator.configure(prop);

Upvotes: 1

zhuwenger
zhuwenger

Reputation: 121

  1. Implement a new log appender which manages FileAppender for different thread and files. Use AppenderSkeleton to do this, maintain a map for FileAppenders.

    public MultiThreadAppender extends AppenderSkeleton {
        public final static String THREAD_KEY = "THREAD_NO";
        private Map<String, FileAppender> fileAppenders;
    }
    
  2. Use MDC to identify different threads. Use a key like "THREAD_NO", put to MDC (MDC.put) when a thread invoke logger the first time, and check this key to get the FileAppender for it. Here's the example:

    protected void append(LoggingEvent event) {
        Object value = event.getMDC(THREAD_KEY);
        FileAppender appender;
        if (value instanceof String && ((String) value).length() > 0) {
            appender = fileAppenders.get(value);
        } else {
            value = nextThreadNo();
            fileAppenders.put(value, new FileAppender(...)); //
        }
    }
    

Upvotes: 1

Matthias Meid
Matthias Meid

Reputation: 12513

You can initialize each logger field with an instance by using LogManager.getLogger(Class) method. By using different text file appenders, you can dump the log lines to an appropriately names text file.

In case each thread used an own Runnable implementation (?), this should work. If it doesn't, try using a ThreadLocal<Logger> as logger and fill it by using LogManager.getLogger(String) with a Thread-widely unique name.

See also Short introduction to log4j: Ceki Gülcü, March 2002 in case you need an example of how to configure appenders.

Upvotes: 1

Thomas Uhrig
Thomas Uhrig

Reputation: 31605

perhaps you could try somezthing like this:

logger = Logger.getLogger(classname);
logger.removeAllAppenders();                                        
logger.addAppender(new FileAppender(layout, "your-thread-name.log", true)); 

you could get the name of your thread with something like "thread.getName()" i think ;)

Upvotes: 2

Shamis Shukoor
Shamis Shukoor

Reputation: 2515

you could use MDC

MDC.put(key,value); --in the code

and %X{key}-- in the file name field in the log4j configuration file

Upvotes: 4

Related Questions