如何在启动时将log4j2配置为带有时间戳的翻转?

时间:2018-02-19 21:05:47

标签: java logging log4j log4j2

我有一个Java应用程序,它通过cron作业每小时运行几分钟(java -jar ...)。它在自己的JVM中运行,而不是在像Tomcat这样的连续运行环境中运行。我正在使用Log4j 2.11进行日志记录。在应用程序中,我有一个具有特定翻转要求的特定记录器:

  1. 登录“rolling.log”
  2. 在每天结束时(或新一天的第一次记录事件),rolling.log应该转到rolling-yyyy-MM-dd.log.gz并且新的记录事件被添加到新的滚动中日志。
  3. 我无法让翻转工作。所有日志消息仅为“rolling.log”,并且始终没有创建rolling-yyyy-MM-dd.log.gz。为了以最简单的方式对此进行测试,我使用以下两个文件创建了一个简单的Java控制台应用程序。我希望只要系统时钟显示不同的分钟,日志文件就会在每次执行时翻转,但这不会发生。

    LoggingTest.java:

    package log4jtest;
    
    import java.time.Instant;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class LoggingTest {
    
        private static final Logger logger = LogManager.getLogger();
    
        public static void main(String[] args) {
            System.out.println(Instant.now() + " - BEGIN: Logging to log4j");
            logger.error("Test log message");
            System.out.println(Instant.now() + " - DONE");
        }
    
    }
    

    log4j2.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE Configuration>
    <Configuration status="WARN">
        <Appenders>
            <RollingFile name="RollingLogFile"
                fileName="logs/rolling.log"
                filePattern="logs/rolling-%d{yyyy-MM-dd-HH-mm}.log.gz"
                createOnDemand="true">
                <PatternLayout
                    pattern="%d{HH:mm:ss.SSS} %-5level - %msg%n" />
                <Policies>
                    <TimeBasedTriggeringPolicy modulate="true"
                        interval="1" />
                    <OnStartupTriggeringPolicy />
                </Policies>
                <DefaultRolloverStrategy />
            </RollingFile>
        </Appenders>
        <Loggers>
            <Root level="error">
                <AppenderRef ref="RollingLogFile" />
            </Root>
        </Loggers>
    </Configuration>
    

    我的猜测是,由于托管应用程序的JVM和Log4j实例在翻转发生时没有运行,因此翻转不会被触发。

    最终,我放弃了使用RollingFileAppender并使用了直接的FileAppender:

    <File name="RollingLogFile" 
            fileName=logs/rolling-${date:yyyy-MM-dd}.log"
            createOnDemand="true">
        <PatternLayout
            pattern="%d{HH:mm:ss.SSS} %-5level - %msg%n" />
    </File>
    

    这有效,但它有一些缺点:

    1. 我无法监控简单命名的“rolling.log”(因为它不存在),但必须使用文件名的日期特定版本。
    2. 我无法在翻转功能上使用log4j的压缩。
    3. 我无法在翻转保留策略中使用log4j的删除。
    4. 因此,重申的问题是:使用log4j,以短暂间隔执行的应用程序是否有可能以与连续运行的应用程序相同的方式使用基于时间的日志文件翻转策略?

2 个答案:

答案 0 :(得分:0)

请尝试以下配置:

<RollingFile name="LogSpecial" 
        fileName="${sys:special.directory}/special.csv" 
        filePattern="${sys:special.directory}/special-%d{yyyy-MM-dd}.csv.gz" 
        createOnDemand="true">
    <CsvParameterLayout />
    <Policies>
        <TimeBasedTriggeringPolicy modulate="true" interval="1" />
        <OnStartupTriggeringPolicy />
    </Policies>
    <DefaultRolloverStrategy>
    <Delete basePath="{sys:special.directory}">
      <IfFileName glob="special-*.csv.gz" />
      <IfLastModified age="60d" />
     </Delete>
    </DefaultRolloverStrategy>
</RollingFile>

您还可以启用log4j2.debug system property来调试此配置并调查错误。

答案 1 :(得分:0)

事实证明,log4j2能够完全按照我的目标行事,但由于未知原因导致部分配置无法正常工作。解决方案是从 RollingFile 元素中删除 createOnDemand =“true”属性。 排除该属性后,以下配置完全按照我的预期工作(在启动时滚动,最多每分钟):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configuration>
<Configuration status="WARN">
    <Appenders>
        <RollingFile name="RollingLogFile"
            fileName="logs/rolling.log"
            filePattern="logs/rolling-%d{yyyy-MM-dd-HH-mm}.log.gz">
            <PatternLayout
                pattern="%d{HH:mm:ss.SSS} %-5level - %msg%n" />
            <TimeBasedTriggeringPolicy />
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="RollingLogFile" />
        </Root>
    </Loggers>
</Configuration>