Log4j: Events appear in the wrong logfile

Posted by Markus on Stack Overflow See other posts from Stack Overflow or by Markus
Published on 2009-08-28T09:10:52Z Indexed on 2010/05/01 15:07 UTC
Read the original article Hit count: 201

Filed under:
|
|
|
|

Hi there!

To be able to log and trace some events I've added a LoggingHandler class to my java project. Inside this class I'm using two different log4j logger instances - one for logging an event and one for tracing an event into different files. The initialization block of the class looks like this:

public void initialize()
{
	System.out.print("starting logging server ...");

	// create logger instances
	logLogger = Logger.getLogger("log");
	traceLogger = Logger.getLogger("trace");

	// create pattern layout
	String conversionPattern = "%c{2} %d{ABSOLUTE} %r %p %m%n";
	try
	{
		patternLayout = new PatternLayout();
		patternLayout.setConversionPattern(conversionPattern);
	}
	catch (Exception e)
	{
		System.out.println("error: could not create logger layout pattern");
		System.out.println(e);
		System.exit(1);
	}

	// add pattern to file appender
	try
	{
		logFileAppender = new FileAppender(patternLayout, logFilename, false);
		traceFileAppender = new FileAppender(patternLayout, traceFilename, false);
	}
	catch (IOException e)
	{
		System.out.println("error: could not add logger layout pattern to corresponding appender");
		System.out.println(e);
		System.exit(1);
	}

	// add appenders to loggers
	logLogger.addAppender(logFileAppender);
	traceLogger.addAppender(traceFileAppender);

	// set logger level
	logLogger.setLevel(Level.INFO);
	traceLogger.setLevel(Level.INFO);

	// start logging server
	loggingServer = new LoggingServer(logLogger, traceLogger, serverPort, this);
	loggingServer.start();

	System.out.println(" done");
}

To make sure that only only thread is using the functionality of a logger instance at the same time each logging / tracing method calls the logging method .info() inside a synchronized-block. One example looks like this:

    public void logMessage(String message)
{
	synchronized (logLogger)
	{
		if (logLogger.isInfoEnabled() && logFileAppender != null)
		{
			logLogger.info(instanceName + ": " + message);
		}
	}
}

If I look at the log files, I see that sometimes a event appears in the wrong file. One example:

trace 10:41:30,773 11080 INFO masterControl(192.168.2.21): string broadcast message was  pushed from 1267093 to vehicle 1055293 (slaveControl 1)
trace 10:41:30,784 11091 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1156513 to vehicle 1105792 (slaveControl 1)
trace 10:41:30,796 11103 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1104306 to vehicle 1055293 (slaveControl 1)
trace 10:41:30,808 11115 INFO masterControl(192.168.2.21): vehicle 1327879 was pushed to slave control 1
10:41:30,808 11115 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1101572 to vehicle 106741 (slaveControl 1)
trace 10:41:30,820 11127 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1055293 to vehicle 1104306 (slaveControl 1)

I think that the problem occures everytime two event happen at the same time (here: 10:41:30,808). Does anybody has an idea how to solve my problem? I already tried to add a sleep() after the method call, but that doesn't helped ...

BR,

Markus

Edit:

logtrace  11:16:07,75511:16:07,755  1129711297  INFOINFO  masterControl(192.168.2.21): string broadcast message was pushed from 1291400 to vehicle 1138272 (slaveControl 1)masterControl(192.168.2.21): vehicle 1333770 was added to slave control 1

or

log 11:16:08,562 12104 INFO 11:16:08,562 masterControl(192.168.2.21): string broadcast message was pushed from 117772 to vehicle 1217744 (slaveControl 1)

12104 INFO masterControl(192.168.2.21): vehicle 1169775 was pushed to slave control 1

Edit 2:

It seems like the problem only occurs if logging methods are called from inside a RMI thread (my client / server exchange information using RMI connections). ...

Edit 3:

I solved the problem by myself: It seems like log4j is NOT completely thread-save. After synchronizing all log / trace methods using a separate object everything is working fine. Maybe the lib is writing the messages to a thread-unsafe buffer before writing them to file?

© Stack Overflow or respective owner

Related posts about java

Related posts about log4j