【发布时间】:2018-07-30 03:50:44
【问题描述】:
我有一个 Java 应用程序,它通过 cron 作业 (java -jar...) 每小时运行几分钟。它在自己的 JVM 中运行,而不是在像 Tomcat 这样的持续运行的环境中。我正在使用 Log4j 2.11 进行日志记录。在应用程序中,我有一个具有特定翻转要求的特定记录器:
- 记录到“rolling.log”
- 在每天结束时(或新一天的第一个日志记录事件),rolling.log 应滚动到 rolling-yyyy-MM-dd.log.gz 并且新的日志记录事件添加到新滚动.log。
我无法让翻转工作。所有日志消息都只发送到“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>
这可行,但有一些缺点:
- 我无法监控简单命名的“rolling.log”(因为它不存在),但必须使用文件名的特定日期版本。
- 我无法使用 log4j 对翻转功能的压缩。
- 我无法使用 log4j 的删除翻转保留策略。
所以,重述的问题是:使用 log4j,在短时间内执行的应用程序是否可以像连续运行的应用程序一样使用基于时间的日志文件翻转策略?
【问题讨论】:
-
你试过
OnStartupTriggeringPolicy吗? -
是的,我确实提到我在我的帖子中尝试了 OnStartupTriggeringPolicy(抱歉,篇幅较长)。它似乎不适用于基于时间的文件模式。
-
这很奇怪。你能用它发布你的配置吗?我已经将它与 DefaultRollingStrategy 的 Delete 操作一起使用,它在类似的情况下对我有用。