Log4j2 - 配置 RolloverStrategy 以删除旧日志文件

Log4j2 - Configure RolloverStrategy to delete old log files

我正在尝试配置 log4j 以仅保留指定数量的备份文件或保留不早于某个年龄的文件。最终我想要 time [daily] 基于触发策略 并保留 30 个备份文件或删除超过 30 天的文件。

经过一些研究,我了解到在使用 时间策略 时我无法指定备份文件的最大数量,但是我遇到了这个问题 https://issues.apache.org/jira/browse/LOG4J2-435 and this documentation fragment http://logging.apache.org/log4j/2.x/manual/appenders.html#CustomDeleteOnRollover,它描述了如何根据文件的年龄和名称模式删除文件。现在,我尝试在简单示例中应用此配置,该示例每分钟创建一个新备份文件,并自动删除 3 分钟之前的文件。为此,我使用以下 pom 创建了简单的 maven 项目:

<?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 配置文件:

<?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>

和主要 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();
            }
        }
    }
}

构建此程序后,您可以 运行 使用以下命令(注意硬编码光盘位置):

java -jar test-1.0-SNAPSHOT.jar

到目前为止,日志文件每分钟创建一次,但没有旧文件被删除。我怎样才能让这个测试配置工作?我应该如何修改此配置,以便最终只保留最近 30 天的文件?

感谢您的帮助。

您的配置和测试程序看起来不错。我测试了你的 Main.java 和 log4j2.xml 配置,它按预期工作:每一分钟触发翻转,删除操作扫描基本目录并仅删除超过 3 分钟的文件。

我没有创建独立的应用程序,而是在我的 IDE 中进行了测试。 (看起来你正在将 log4j jar 文件和你的 class 和配置隐藏到一个 jar 中。这会导致问题吗?)

通过将配置更改为 <Configuration status="TRACE" ... 启用 log4j 内部日志记录后,我得到以下输出:

  • 迭代 3:尚未删除任何文件:最旧的文件存在 173 秒。
  • 迭代 4:最旧的文件被删除。

...(省略启动日志)...

log iteration: 3
2016-01-16 14:26:23,192 main TRACE PatternProcessor.getNextTime returning 2016/01/16-14:27:00.000, nextFileTime=2016/01/16-14:26:59.000, prevFileTime=2016/01/16-14:25:59.000, current=2016/01/16-14:26:23.192, freq=EVERY_SECOND
2016-01-16 14:26:23,193 main TRACE DefaultRolloverStrategy.purge() took 0.0 milliseconds
2016-01-16 14:26:23,194 main DEBUG RollingFileManager executing synchronous FileRenameAction[c:\temp\log\app.log to c:\temp\log\app-2016-01-16-14-25-59.log, renameEmptyFiles=false]
2016-01-16 14:26:23,198 main DEBUG RollingFileManager executing async CompositeAction[DeleteAction[basePath=c:\temp\log, options=[], maxDepth=1, conditions=[IfFileName(glob:app-*.log), IfLastModified(age=PT3M)]]]
2016-01-16 14:26:23,199 Log4j2-2 DEBUG Starting DeleteAction[basePath=c:\temp\log, options=[], maxDepth=1, conditions=[IfFileName(glob:app-*.log), IfLastModified(age=PT3M)]]
2016-01-16 14:26:23,200 Log4j2-2 DEBUG DeleteAction complete in 0.001186309 seconds
2016-01-16 14:26:23,201 Log4j2-2 TRACE Sorted paths:
2016-01-16 14:26:23,201 Log4j2-2 TRACE c:\temp\log\app.log (modified: 2016-01-16T05:26:23.199631Z)
2016-01-16 14:26:23,201 Log4j2-2 TRACE c:\temp\log\app-2016-01-16-14-25-59.log (modified: 2016-01-16T05:25:30.832634Z)
2016-01-16 14:26:23,203 Log4j2-2 TRACE c:\temp\log\app-2016-01-16-14-24-59.log (modified: 2016-01-16T05:25:23.188525Z)
2016-01-16 14:26:23,203 Log4j2-2 TRACE c:\temp\log\app-2016-01-16-14-23-59.log (modified: 2016-01-16T05:23:29.466887Z)
2016-01-16 14:26:23,204 Log4j2-2 TRACE IfFileName REJECTED: 'glob:app-*.log' does not match relative path 'app.log'
2016-01-16 14:26:23,204 Log4j2-2 TRACE Not deleting base=c:\temp\log, relative=app.log
2016-01-16 14:26:23,205 Log4j2-2 TRACE IfFileName ACCEPTED: 'glob:app-*.log' matches relative path 'app-2016-01-16-14-25-59.log'
2016-01-16 14:26:23,205 Log4j2-2 TRACE IfLastModified REJECTED: app-2016-01-16-14-25-59.log ageMillis '52373' < 'PT3M'
2016-01-16 14:26:23,205 Log4j2-2 TRACE Not deleting base=c:\temp\log, relative=app-2016-01-16-14-25-59.log
2016-01-16 14:26:23,206 Log4j2-2 TRACE IfFileName ACCEPTED: 'glob:app-*.log' matches relative path 'app-2016-01-16-14-24-59.log'
2016-01-16 14:26:23,206 Log4j2-2 TRACE IfLastModified REJECTED: app-2016-01-16-14-24-59.log ageMillis '60018' < 'PT3M'
2016-01-16 14:26:23,206 Log4j2-2 TRACE Not deleting base=c:\temp\log, relative=app-2016-01-16-14-24-59.log
2016-01-16 14:26:23,206 Log4j2-2 TRACE IfFileName ACCEPTED: 'glob:app-*.log' matches relative path 'app-2016-01-16-14-23-59.log'
2016-01-16 14:26:23,207 Log4j2-2 TRACE IfLastModified REJECTED: app-2016-01-16-14-23-59.log ageMillis '173740' < 'PT3M'
2016-01-16 14:26:23,207 Log4j2-2 TRACE Not deleting base=c:\temp\log, relative=app-2016-01-16-14-23-59.log
log iteration: 4
2016-01-16 14:27:23,200 main TRACE PatternProcessor.getNextTime returning 2016/01/16-14:28:00.000, nextFileTime=2016/01/16-14:27:59.000, prevFileTime=2016/01/16-14:26:59.000, current=2016/01/16-14:27:23.200, freq=EVERY_SECOND
2016-01-16 14:27:23,201 main TRACE DefaultRolloverStrategy.purge() took 0.0 milliseconds
2016-01-16 14:27:23,202 main DEBUG RollingFileManager executing synchronous FileRenameAction[c:\temp\log\app.log to c:\temp\log\app-2016-01-16-14-26-59.log, renameEmptyFiles=false]
2016-01-16 14:27:23,204 main DEBUG RollingFileManager executing async CompositeAction[DeleteAction[basePath=c:\temp\log, options=[], maxDepth=1, conditions=[IfFileName(glob:app-*.log), IfLastModified(age=PT3M)]]]
2016-01-16 14:27:23,205 Log4j2-3 DEBUG Starting DeleteAction[basePath=c:\temp\log, options=[], maxDepth=1, conditions=[IfFileName(glob:app-*.log), IfLastModified(age=PT3M)]]
2016-01-16 14:27:23,207 Log4j2-3 DEBUG DeleteAction complete in 0.001230382 seconds
2016-01-16 14:27:23,207 Log4j2-3 TRACE Sorted paths:
2016-01-16 14:27:23,207 Log4j2-3 TRACE c:\temp\log\app.log (modified: 2016-01-16T05:27:23.20571Z)
2016-01-16 14:27:23,208 Log4j2-3 TRACE c:\temp\log\app-2016-01-16-14-26-59.log (modified: 2016-01-16T05:26:23.946671Z)
2016-01-16 14:27:23,208 Log4j2-3 TRACE c:\temp\log\app-2016-01-16-14-25-59.log (modified: 2016-01-16T05:25:30.832634Z)
2016-01-16 14:27:23,209 Log4j2-3 TRACE c:\temp\log\app-2016-01-16-14-24-59.log (modified: 2016-01-16T05:25:23.188525Z)
2016-01-16 14:27:23,209 Log4j2-3 TRACE c:\temp\log\app-2016-01-16-14-23-59.log (modified: 2016-01-16T05:23:29.466887Z)
2016-01-16 14:27:23,210 Log4j2-3 TRACE IfFileName REJECTED: 'glob:app-*.log' does not match relative path 'app.log'
2016-01-16 14:27:23,210 Log4j2-3 TRACE Not deleting base=c:\temp\log, relative=app.log
2016-01-16 14:27:23,211 Log4j2-3 TRACE IfFileName ACCEPTED: 'glob:app-*.log' matches relative path 'app-2016-01-16-14-26-59.log'
2016-01-16 14:27:23,211 Log4j2-3 TRACE IfLastModified REJECTED: app-2016-01-16-14-26-59.log ageMillis '59265' < 'PT3M'
2016-01-16 14:27:23,211 Log4j2-3 TRACE Not deleting base=c:\temp\log, relative=app-2016-01-16-14-26-59.log
2016-01-16 14:27:23,212 Log4j2-3 TRACE IfFileName ACCEPTED: 'glob:app-*.log' matches relative path 'app-2016-01-16-14-25-59.log'
2016-01-16 14:27:23,212 Log4j2-3 TRACE IfLastModified REJECTED: app-2016-01-16-14-25-59.log ageMillis '112380' < 'PT3M'
2016-01-16 14:27:23,212 Log4j2-3 TRACE Not deleting base=c:\temp\log, relative=app-2016-01-16-14-25-59.log
2016-01-16 14:27:23,213 Log4j2-3 TRACE IfFileName ACCEPTED: 'glob:app-*.log' matches relative path 'app-2016-01-16-14-24-59.log'
2016-01-16 14:27:23,213 Log4j2-3 TRACE IfLastModified REJECTED: app-2016-01-16-14-24-59.log ageMillis '120025' < 'PT3M'
2016-01-16 14:27:23,213 Log4j2-3 TRACE Not deleting base=c:\temp\log, relative=app-2016-01-16-14-24-59.log
2016-01-16 14:27:23,214 Log4j2-3 TRACE IfFileName ACCEPTED: 'glob:app-*.log' matches relative path 'app-2016-01-16-14-23-59.log'
2016-01-16 14:27:23,214 Log4j2-3 TRACE IfLastModified ACCEPTED: app-2016-01-16-14-23-59.log ageMillis '233748' >= 'PT3M'
2016-01-16 14:27:23,214 Log4j2-3 TRACE Deleting c:\temp\log\app-2016-01-16-14-23-59.log

您可以启用状态日志记录并显示您的输出吗?