[英]Why Log4j2's RollingFile appender prevents a stand alone application to terminate for 60 sec?
這段代碼重現了我認為是Log4j2的錯誤。 這是一個簡單的循環,它通過兩個附加程序記錄2000條消息:控制台附加程序和滾動文件附加程序,每5Kb滾動文件一次。 為了重現我認為是錯誤的缺陷,此限制故意較低。
這是代碼。
package bug;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Example {
private static final Logger logger = LogManager.getLogger(Example.class);
public static void main(String[] args) throws InterruptedException {
for(int i = 0; i<2000; i++){
logger.info("This is log message #{}.", i);
Thread.sleep(0);
}
}
}
這是log4j2.xml
配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="TRACE">
<Appenders>
<Console name="stdout" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %p %m%n"/>
</Console>
<RollingFile name="roll-by-size"
fileName="target/log4j2/roll-by-size/app.log"
filePattern="target/log4j2/roll-by-size/app.%i.log.gz"
ignoreExceptions="false"
append="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy
size="5 KB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="bug" level="TRACE">
<AppenderRef ref="roll-by-size"/>
</Logger>
<Root level="DEBUG">
<AppenderRef ref="stdout"/>
</Root>
</Loggers>
</Configuration>
奇怪的是,當啟動應用程序時,您將在控制台中看到此日志。
2016-12-22 22:12:36 INFO This is log message #1993.
2016-12-22 22:12:36 INFO This is log message #1994.
2016-12-22 22:12:36 INFO This is log message #1995.
2016-12-22 22:12:36 INFO This is log message #1996.
2016-12-22 22:12:36 INFO This is log message #1997.
2016-12-22 22:12:36 INFO This is log message #1998.
2016-12-22 22:12:36 INFO This is log message #1999.
2016-12-22 22:13:36,380 pool-1-thread-1 DEBUG Stopping LoggerContext[name=60199c81, org.apache.logging.log4j.core.LoggerContext@4597ec68]
2016-12-22 22:13:36,380 pool-1-thread-1 DEBUG Stopping LoggerContext[name=60199c81, org.apache.logging.log4j.core.LoggerContext@4597ec68]...
2016-12-22 22:13:36,381 pool-1-thread-1 TRACE Unregistering 1 MBeans: [org.apache.logging.log4j2:type=60199c81]
2016-12-22 22:13:36,381 pool-1-thread-1 TRACE Unregistering 1 MBeans: [org.apache.logging.log4j2:type=60199c81,component=StatusLogger]
2016-12-22 22:13:36,381 pool-1-thread-1 TRACE Unregistering 1 MBeans: [org.apache.logging.log4j2:type=60199c81,component=ContextSelector]
2016-12-22 22:13:36,381 pool-1-thread-1 TRACE Unregistering 2 MBeans: [org.apache.logging.log4j2:type=60199c81,component=Loggers,name=bug, org.apache.logging.log4j2:type=60199c81,component=Lo
ggers,name=]
2016-12-22 22:13:36,381 pool-1-thread-1 TRACE Unregistering 2 MBeans: [org.apache.logging.log4j2:type=60199c81,component=Appenders,name=roll-by-size, org.apache.logging.log4j2:type=60199c81,c
omponent=Appenders,name=stdout]
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=60199c81,component=AsyncAppenders,name=*'
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=60199c81,component=AsyncLoggerRingBuffer'
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=60199c81,component=Loggers,name=*,subtype=RingBuffer'
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE Stopping XmlConfiguration[location=C:\Users\danidemi\workspace\bug-log4j2-hanging-up-before-shutdown\target\classes\log4j2.xml]...
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE XmlConfiguration notified 3 ReliabilityStrategies that config will be stopped.
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE XmlConfiguration stopping 2 LoggerConfigs.
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE XmlConfiguration stopping root LoggerConfig.
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE XmlConfiguration notifying ReliabilityStrategies that appenders will be stopped.
2016-12-22 22:13:36,382 pool-1-thread-1 TRACE XmlConfiguration stopping remaining Appenders.
2016-12-22 22:13:36,383 pool-1-thread-1 DEBUG Shutting down RollingFileManager target/log4j2/roll-by-size/app.log
2016-12-22 22:13:36,383 pool-1-thread-1 DEBUG Shut down RollingFileManager target/log4j2/roll-by-size/app.log, all resources released: true
2016-12-22 22:13:36,383 pool-1-thread-1 DEBUG Shutting down OutputStreamManager SYSTEM_OUT.false.false
2016-12-22 22:13:36,383 pool-1-thread-1 DEBUG Shut down OutputStreamManager SYSTEM_OUT.false.false, all resources released: true
2016-12-22 22:13:36,384 pool-1-thread-1 TRACE XmlConfiguration stopped 2 remaining Appenders.
2016-12-22 22:13:36,384 pool-1-thread-1 TRACE XmlConfiguration cleaning Appenders from 3 LoggerConfigs.
2016-12-22 22:13:36,384 pool-1-thread-1 DEBUG Stopped XmlConfiguration[location=C:\Users\danidemi\workspace\bug-log4j2-hanging-up-before-shutdown\target\classes\log4j2.xml] OK
2016-12-22 22:13:36,385 pool-1-thread-1 DEBUG Stopped LoggerContext[name=60199c81, org.apache.logging.log4j.core.LoggerContext@4597ec68]...
奇怪的是最后一個日志是在某個時間發布的...
2016-12-22 22:12:36 INFO This is log message #1999.
但是log4j2的關閉恰好在最后一條“業務”日志消息之后一分鍾開始。
2016-12-22 22:13:36,380 pool-1-thread-1 DEBUG Stopping LoggerContext[name=60199c81, org.apache.logging.log4j.core.LoggerContext@4597ec68]
這就是問題! 業務邏輯終止,但是log4j2等待一分鍾,然后允許該應用停止! 為什么 ? 我希望該應用程序可以像人們期望的那樣立即停止。
我調查了一下... 60秒的延遲似乎或多或少與記錄的消息數量無關。
但是,如果您更改log4j2.xml
將大小從log4j2.xml
...
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="5 KB"/>
</Policies>
至5Mb ...
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="5 MB"/>
</Policies>
...,使應用程序在最后一條日志消息之后立即停止。 5Mb是一個足夠大的限制,不需要實際進行滾動。 因此,我認為正是滾動本身以某種方式導致了這種延遲的發生。 我認為這是一個錯誤,但是...您認為呢?
我在GitHub上建立了一個小型Maven項目,演示了我在這里試圖解釋的內容。
感謝您向Log4j2社區提出此問題 。
根本原因是Log4j創建了兩個ThreadPoolExecutor,一個守護程序和一個非守護程序。 這些執行程序是使用默認設置創建的,該默認設置將線程keepAliveTime設置為一分鍾。
在該示例中,應用程序在觸發過渡后立即關閉。 翻轉將非守護程序執行程序中的舊文件壓縮到后台線程中。 因為執行程序使該線程保持活動狀態一分鍾,而這是一個非守護程序線程,所以整個應用程序將保持活動狀態一分鍾。
這只會影響過渡后立即退出的應用程序。
更新2016-12-26:此問題已修復。 從2.8開始,默認情況下,非守護程序線程將具有較短(一秒)的keepAliveTime。
您可以嘗試使用LogManager.shutdown()
作為程序的最后一個命令。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.