LOG4J - how to control log file name?


My Java application create a number of instances of the same application (let say - executor).
But I need that different instances of the same application writes different log files.

Another important thing I need is - all such log files should have log filename containing the current date in a format - YYYYMMDD and ProcessID of the process which writing this log file.
So, finally I expect following files on a disk:
and so on.

Could you please give me some hints/ideas how can I do this with LOG4J (v1.2.16)?

Btw, please see the example of my log4j.properties enclosed.

log4j.logger.Monitor=TRACE, monitorLog, stdout
log4j.logger.Executor=TRACE, executorLog
log4j.logger.bto.utils.ThreadPool=WARN, threadPool

log4j.appender.stdout.layout.conversionPattern=%d{ABSOLUTE} %m%n

log4j.appender.monitorLog.layout.conversionPattern=%d{ABSOLUTE} %m%n

log4j.appender.executorLog.layout.conversionPattern=%d{ABSOLUTE} %m%n

Open in new window

Who is Participating?
Sathish David Kumar NArchitectCommented:
you want to define in rootCategory...
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Dmitry_BondAuthor Commented:
Ok. I have tried to set log file name using the approach described at
But unfortunately it makes all messages on console duplicated! :-(((
But why?!
Messages in a log file are not duplicated, only in console.
Looks completely weird!
Any ideas what could be wrong with it?
Dmitry_BondAuthor Commented:
Btw, may you see something wrong in a code...
public static Appender findLogAppender(String pLogName, Class pLogAppenderClass)
	Logger log = Logger.getLogger(pLogName);
	Enumeration appenders = log.getAllAppenders();
	while (appenders.hasMoreElements())
		Appender currAppender = (Appender)appenders.nextElement();
		if (pLogAppenderClass.isInstance(currAppender))
			return currAppender;
	return null;

public static void setLogFilename(String pLogName)
	Object logAppender = MiscUtils.findLogAppender(pLogName, org.apache.log4j.FileAppender.class);
	if (logAppender != null)
		FileAppender fa = (FileAppender)logAppender;
		String fn = fa.getFile();			
		String fp = includeTrailing(exctractFilePath(fn), File.separatorChar);
		fn = MiscUtils.exctractFileNameNoExt(fn);
		fn = fp + fn + "-" + MiscUtils.getDateStamp('\0') + ".log";

// then init 2 loggers:
setLogFilename("Monitor"); // in main application
setLogFilename("Executor"); // in executor application

Open in new window

Dmitry_BondAuthor Commented:
Btw, I found duplicated console messages - it was my mistake. I copied log4j.properties file to project folder, so Eclipse included it into a JAR. So, it seems 2 similar log4j.properties files (one in JAR), second in directory with JAR caused console messages duplicated. As for me it looks like a bug in LOG4J - I believe it should not take into account duplicated log4j.properties; assume same names and same properties for logger should not create duplicated objects.

Ok. But my question is - what can i do with the empty log files (monitor.log and executor.log) which was created on application start. Looks like LOG4J initialize and create default log files before I set log filenames. Is there any way to avoid it? I mean - standard way. Prefer to avoid coding custom functionality if possible.
Dmitry_BondAuthor Commented:
Ok... Seems I have solved all logging problems.
Not the way I like but at least it working fine.

So, took the code from

Change the "setFile" method to

      public synchronized void setFile(String fileName, boolean append,
                  boolean bufferedIO, int bufferSize) throws IOException
            SimpleDateFormat sdf = new SimpleDateFormat(fileBackup);
            String actualFileName = sdf.format(new Date());
            actualFileName = actualFileName.replaceAll("\\$PID", MiscUtils.getPID());
            super.setFile(actualFileName, append, bufferedIO, bufferSize);

Implemented "getPID()" method as

      public static String getPID()
            String pid = ManagementFactory.getRuntimeMXBean().getName();
            int p = pid.indexOf('@');
            if (p >= 0)
                  pid = pid.substring(0, p);
            return pid;

Then split log4j.xml config file to 2 separate files - log4j-mon.xml (for monitor app) and log4j-exec.xml (for executor app).

Then adjusted command line which starts monitor application and command line which starts executor application:

java.exe -Dlog4j.configuration=log4j-mon.xml Monitor
java.exe -Dlog4j.configuration=log4j-exec.xml MonExecutor

So, seems now everything is working fine. No dummy files, no duplicated messages.

Thank you very much for help!

Dmitry_BondAuthor Commented:
After some experiments and adjustments I finally make solution working. Thanks.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.