I'm trying to configure log4j to keep only specified amount of backup files or keep files that are not older than some age. Ultimately I want to have time [daily] based triggering policy and keep 30 backup files or delete files that are older then 30 days.
After doing some research I learned that I can't specify max number of backup files when using time policy however I came across this issue https://issues.apache.org/jira/browse/LOG4J2-435 and this documentation fragment http://logging.apache.org/log4j/2.x/manual/appenders.html#CustomDeleteOnRollover that describes how to delete files based on their age and name pattern. Now I'm trying to apply this configuration in simple example that will create new backup file every minute and will automatically delete files that are older then 3 minutes. To do this I created simple maven project with following pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>test.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
log4j2.xml config file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="D:/app.log"
filePattern="D:/app-%d{yyyy-MM-dd-HH-mm-ss}.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="60" modulate="true"/>
<!--<SizeBasedTriggeringPolicy size="250 MB"/>-->
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="D:" maxDepth="1">
<IfFileName glob="app-*.log" />
<IfLastModified age="3m" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
and Main class:
package test;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Created by mzurawski on 2015-12-22.
*/
public class Main {
final static Logger logger = LogManager.getLogger(Main.class);
public static void main(String[] args) {
runMe("test");
}
private static void runMe(String parameterParam){
String parameter;
for(int i=0; i<100; ++i) {
parameter = parameterParam + i;
System.out.println("log iteration: "+i);
if (logger.isDebugEnabled()) {
logger.debug("This is debug : " + parameter);
}
if (logger.isInfoEnabled()) {
logger.info("This is info : " + parameter);
}
logger.warn("This is warn : " + parameter);
logger.error("This is error : " + parameter);
logger.fatal("This is fatal : " + parameter);
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
after building this program you can run it with following command (watch out for hard coded disc locations):
java -jar test-1.0-SNAPSHOT.jar
So far the log files are created every minute but no old files are being deleted. How can I get this test configuration to work? How should I modify this configuration so that ultimately only files from last 30 days will be kept?
Thanks for any help.
Your configuration and test program look fine. I tested your Main.java and log4j2.xml configuration and it works as expected: every minute the rollover is triggered, the Delete action scans the base directory and deletes only files older than 3 minutes.
I did not create a standalone app, but tested in my IDE instead. (Looks like you are shading the log4j jar files and your class and config into a single jar. Could that cause the issue?)
After enabling log4j internal logging by changing the config to
<Configuration status="TRACE" ...
, I get the following output:... (startup log omitted)...
Can you enable status logging and show your output?