When to Use It:
You want your log file that opens as a new file every time the application runs. The previous log file will be saved with a serial number appended to its file name.For example,
stdout.log
stdout.log.1
stdout.log.2
...
How to Do It:
Let the code explain everything.import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Files;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.ErrorCode;
public class EveryRunRollingFileAppender extends FileAppender {
public EveryRunRollingFileAppender() {
super();
}
public EveryRunRollingFileAppender(Layout layout, String filename,
boolean append, boolean bufferedIO, int bufferSize)
throws IOException {
super(layout, filename, append, bufferedIO, bufferSize);
}
public EveryRunRollingFileAppender(Layout layout, String filename, boolean append)
throws IOException {
super(layout, filename, append);
}
public EveryRunRollingFileAppender(Layout layout, String filename)
throws IOException {
super(layout, filename);
}
@Override
public void activateOptions() {
if (fileName != null) {
try {
rollLogFile();
setFile(fileName, false, bufferedIO, bufferSize);
} catch (IOException e) {
errorHandler.error("setFile(" + fileName + "," + fileAppend
+ ") call failed.", e, ErrorCode.FILE_OPEN_FAILURE);
}
} else {
LogLog.warn("File option not set for appender [" + name + "].");
LogLog.warn("Are you using FileAppender instead of ConsoleAppender?");
}
}
private void rollLogFile() throws IOException {
File logFile = new File(fileName);
if (!logFile.exists()) {
return;
}
String logFilenameSuffix = logFile.getName() + ".";
File logDir = logFile.getParentFile();
String[] logFilenames = logDir.list(new RollingFilenameFilter(logFilenameSuffix));
long lastLogFileSeq = 0;
for (String logFilename : logFilenames) {
String logFileSeqName = logFilename.substring(
logFilename.lastIndexOf(logFilenameSuffix) + logFilenameSuffix.length());
try {
long logFileSeq = Long.valueOf(logFileSeqName);
if (logFileSeq > lastLogFileSeq) {
lastLogFileSeq = logFileSeq;
}
} catch (NumberFormatException e) {
}
}
StringBuilder rollingLogFilename = new StringBuilder(fileName);
rollingLogFilename.append(".");
rollingLogFilename.append(lastLogFileSeq + 1);
File rollingLogFile = new File(rollingLogFilename.toString());
Files.copy(logFile.toPath(), rollingLogFile.toPath());
}
private static class RollingFilenameFilter implements FilenameFilter {
private final String logFilenameSuffix;
RollingFilenameFilter(String logFilenameSuffix) {
this.logFilenameSuffix = logFilenameSuffix;
}
@Override
public boolean accept(File dir, String name) {
return name.lastIndexOf(logFilenameSuffix) != -1;
}
}
}
How to Use It:
Set the custom appender in your log4j.properties.log4j.appender.file=com.foo.logging.EveryRunRollingFileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-5p %d{ISO8601} [%c.%M():%L] - %m%n
log4j.appender.file.file=stdout.log