如何以编程方式配置log4j 2.5 RollingRandomAccessFileAppender以限制文件而不重命名?

时间:2016-05-25 00:42:35

标签: java log4j2

我有数千个使用log4j2创建日志的进程,并且由于文件系统的负担,重命名每次翻转时的所有文件都是不可接受的。

目前我有以下代码来创建Appender:

PathCondition[] pathConditions = new PathCondition[1];
pathConditions[0] = IfAccumulatedFileCount.createFileCountCondition(10);

DeleteAction deleteAction = DeleteAction.createDeleteAction(basePath, true, 1, true, null, pathConditions, null, config);
Action[] actions = new Action[1];
actions[0] = deleteAction;

String filename = "file";
String filePattern = fileName + "_%i.log";
RollingRandomAccessFileAppender appender = RollingRandomAccessFileAppender.createAppender(
      fileName,
      filePattern,
      "false", // append
      "RollingRandomAccessFileAppender", // name
      "true", // immediateFlush
      "8192", // bufferSizeStr
      SizeBasedTriggeringPolicy.createPolicy(Long.valueOf(maxFileSizeInMB*1024*1024).toString()),
      DefaultRolloverStrategy.createStrategy(Integer.valueOf(Integer.MAX_VALUE).toString(), "1", "max", null, actions, true, config),
      getLayout(),
      null, // filter
      "true", // ignore exceptions (they get logged)
      "false", // advertise
      "", // advertiseURI
      config);

但是当我运行它时,我的进程被操作系统谋杀,因为它是垃圾邮件文件系统试图统计1和Integer.MAX_VALUE之间的每个文件,这非常震惊(看起来像一个缺陷,在发现一个不存在之后)文件没有理由寻找后续数字),来自strace -f:

...
[pid 18155] stat("file_2147412901.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412901.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412900.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412900.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412899.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412899.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412898.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412898.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412897.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412897.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412896.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412896.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412895.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412895.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412894.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412894.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412893.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412893.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412892.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412892.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
[pid 18155] stat("file_2147412891.log", 0x2b74134f96d0) = -1 ENOENT (No such file or directory)
...

发生这种情况时,JVM中的堆栈跟踪:

at java.io.UnixFileSystem.getBooleanAttributes0(Native Method)
at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:242)
at java.io.File.exists(File.java:819)
at org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy.purgeAscending(DefaultRolloverStrategy.java:305)
at org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy.purge(DefaultRolloverStrategy.java:279)
at org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy.rollover(DefaultRolloverStrategy.java:506)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.rollover(RollingFileManager.java:196)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.rollover(RollingFileManager.java:124)
- locked <0x00000005c0196238> (a org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileManager)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.checkRollover(RollingFileManager.java:119)
- locked <0x00000005c0196238> (a org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileManager)
at org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender.append(RollingRandomAccessFileAppender.java:89)
at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:152)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:125)
at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:116)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:390)
at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:378)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:362)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:352)
at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:63)
at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:147)
at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:1011)
at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:988)
at org.apache.logging.log4j.spi.AbstractLogger.log(AbstractLogger.java:866)

我试图这样做是为了防止文件重命名,这样我就可以以某种方式使用DeleteAction来保持文件数量的下降,同时仍让它们滚动到任意高的数字。

1 个答案:

答案 0 :(得分:1)

如果您阅读DefaultRolloverStrategy上的文档,您将看到它描述了这种行为。它真的是为你保留一个相当小的,固定数量的文件而不是任意数字。

对于你想要做的事情,我会认为添加一个像“无限”或无任何东西的fileIndex值,根本不会尝试清除文件,而是依赖你的DeleteAction配置是有意义的。我建议你为此创建一个jira问题。如果你能提供更好的补丁。

更新:从版本2.8开始,Log4j不再尝试查找min和max之间的所有文件,只查看实际位于磁盘上的文件。这应该有助于消除您遇到的问题。此外,在同一版本中添加了一项新功能,允许您直接写入已滚动的文件,因此根本不需要重命名。