Log4j - How to include date / time in filenames AND delete old logs?

My boss requires me to have a registration solution where

  • All log files have date / time in the filename (e.g. myapp.2-28-2012.log)
  • Only the most recent log files remain. Older log files are deleted, so there is not enough space on the hard disk.

It seems with log4j I can only get one or the other criteria, but not both. With the log4j extras TimeBasedRollingPolicy I can get the log files to contain the date / time that does 1. However, there doesn't seem to be a way for the TimeBasedRollingPolicy to delete the old log files. According to this post, it is not possible to force TimeBasedRollingPolicy to delete old log files

With the log4j extras FixedWindowRollingPolicy and SizeBasedTriggeringPolicy, I can get log4j to delete all but the last 10 log files, so my hard drive doesn't run out of space by filling up 2. However, I can't get this solution to put the date / time in the filename. With this configuration

def myAppAppender = new org.apache.log4j.rolling.RollingFileAppender(name: 'myApp', layout: pattern(conversionPattern: "%m%n"))
def rollingPolicy = new org.apache.log4j.rolling.FixedWindowRollingPolicy(fileNamePattern: '/tmp/myapp-%d{MM-dd-yyyy_HH:mm:ss}.log.%i',maxIndex:10,activeFileName: '/tmp/myapp.log')
def triggeringPolicy = new org.apache.log4j.rolling.SizeBasedTriggeringPolicy(maxFileSize:10000000)


collapsed log files do not contain date / time. They look like this:



Can both criteria 1) and 2) be met with log4j? Should I subclass TimeBasedRollingPolicy? If so, what methods should you override?


source to share

1 answer

Log4j is somewhat tricky to do, but you can always extend the policy to suit your specific needs as follows.

First, you need to copy the original TimeBasedRollingPolicy into a new class such as MyAppDeletingTimeBasedRollingPolicy. The Apache license allows this.

The most important task is to implement the deletion logic according to your needs. Below is my class that removes files from "myapp-debug" to "gz" and hasn't been changed in 3 days. You will probably need other checks, so be careful when blindly copying and pasting code.

private static class DeleteOldMyAppLogFilesInDirAction extends ActionBase {

    private static final long MAX_HISTORY = 3l * 24 * 60 * 60 * 1000; //3 days
    private File dir;

    public DeleteOldMyAppLogFilesInDirAction (File dir) {
        this.dir = dir;

    public boolean execute() throws IOException {
        for (File f : dir.listFiles()) {
            if (f.getName().startsWith("myapp-debug.") && f.getName().endsWith(".gz")
                    && f.lastModified() < System.currentTimeMillis() - MAX_HISTORY) {
        return true;



Then you need to change the return value:

    return new RolloverDescriptionImpl(nextActiveFile, false, renameAction, compressAction);


For this:

    Action deleteOldFilesAction = new DeleteOldMyAppLogFilesInDirAction (new File(currentActiveFile).getParentFile());
    List<Action> asynchActions = new ArrayList<Action>();
    if (compressAction != null) {

    return new RolloverDescriptionImpl(nextActiveFile, false, renameAction, new CompositeAction(asynchActions, false));


This class has some hard-coded assumptions such as the filename and old files in the same directory as the current file, be careful with these assumptions and be prepared to hack your path for your own needs.



All Articles