Reputation: 1721
I'm just working on an application where I gotta maintain logs based on size, and I have done so as below code snippet, what I was expecting was after every 10MB, a new log roller say Mylog.1.log, Mylog.2.log and so on will be created, unfortunately its not happening.
Though it creates Mylog.1.log, post that its removing Mylog.1.log and creating Mylog.2.log, this is not expected behaviour.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true"
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="append" value="true"/>
<param name="file" value="E:/logs/Mylog.log"/>
<param name="MaxFileSize" value="10MB"/>
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="fileAppender"/>
</root>
Environment OS : Windows 7 Application Server : IBM Websphere 8 Programming language : java
Googled a lot, result doesnt seems fruitful, any help is appreciated. Thanks.
Upvotes: 1
Views: 9540
Reputation: 345
This happens because in rollOver()
method in RollingFileAppender.java
, renaming of the current log file is failing.
renameSucceeded = file.renameTo(target);
Here file.renameTo(target)
returns false. To solve this, override the method and add custom code to fix the issue. One way to do is add the below code after the above statement.
if(!renameSucceeded) //custom code begins
{
try
{
FileUtils.copyFile(file, target);
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
bw.write("");
bw.flush();
bw.close();
renameSucceeded = true;
}
catch (IOException e) {
renameSucceeded = false;
}
}
Upvotes: 0
Reputation: 6180
We have the below log4j configuration running well in production. The log4j version used is 1.2.15
<appender name="FILE_JVM" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="E:/logs/app.log"/>
<param name="maxFileSize" value="20MB"/>
<param name="maxBackupIndex" value="50"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
Comparing it with your I just the case of params maxFileSize & maxBackupIndex different.
I tried a sample with log4j 1.2.17 and was able to see the logs getting rolled over with app.log.1, app.log.2, app.log.3 and so on files in my logs directory. Try running it at your end and see what could be missing.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<appender name="FILE_JVM" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="E:/Sundry/Projects/Log4jEmailSample/logs/app.log"/>
<param name="maxFileSize" value="1MB"/>
<param name="maxBackupIndex" value="50"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<!-- the ROOT Logger -->
<root>
<level value="INFO"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE_JVM"/>
</root>
</log4j:configuration>
Below the standalone app
import org.apache.log4j.Logger;
import java.util.concurrent.TimeUnit;
public class MainApp {
public static void main(String[] args) {
Logger logger = Logger.getLogger(MainApp.class);
while (true) {
logMessages(logger);
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
private static void logMessages(Logger logger) {
logger.info("Info message");
}
}
The only jar I have in my class path is log4j-1.2.17.jar. Does it work at your end?
Upvotes: 1