Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么使用Log4j2';s RollingFile appender阻止独立应用程序终止60秒?_Java_Logging_Log4j2_Rollingfileappender_Shutdown Hook - Fatal编程技术网

Java 为什么使用Log4j2';s RollingFile appender阻止独立应用程序终止60秒?

Java 为什么使用Log4j2';s RollingFile appender阻止独立应用程序终止60秒?,java,logging,log4j2,rollingfileappender,shutdown-hook,Java,Logging,Log4j2,Rollingfileappender,Shutdown Hook,这段代码复制了我认为是Log4j2的一个bug。 这是一个简单的循环,使用两个附加器记录2000条消息: 控制台追加器和滚动文件追加器,用于滚动文件 每5公里。为了重现我认为是错误的东西,这个限制是故意降低的 这是密码 package bug; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Example { private stati

这段代码复制了我认为是Log4j2的一个bug。 这是一个简单的循环,使用两个附加器记录2000条消息: 控制台追加器和滚动文件追加器,用于滚动文件 每5公里。为了重现我认为是错误的东西,这个限制是故意降低的

这是密码

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);
        }
    }

}
奇怪的是,当应用程序启动时,您会在控制台中看到这些日志

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
将大小从5Kb增加

<Policies>
    <OnStartupTriggeringPolicy/>
    <SizeBasedTriggeringPolicy size="5 KB"/>
</Policies>

到5Mb

<Policies>
    <OnStartupTriggeringPolicy/>
    <SizeBasedTriggeringPolicy size="5 MB"/>
</Policies>

。。。这使得应用程序在最后一条日志消息之后立即停止。 5Mb是一个足够大的限制,不需要实际进行轧制。 所以我认为这是滚动本身,在某种程度上使这种延迟发生。 我认为这是一个错误,但是。。。你觉得怎么样


我已经在上建立了一个小型Maven项目,演示了我在这里试图解释的内容。

您可以尝试使用
LogManager.shutdown()
作为程序的最后一个命令。

感谢您对Log4j2社区的支持

根本原因是Log4j创建了两个threadpoolexecutor,一个守护进程和一个非守护进程。这些执行器是使用默认设置创建的,该设置将线程keepAliveTime设置为一分钟

在本例中,应用程序在触发滚动后立即关闭。滚动将压缩非守护进程执行器中后台线程中的旧文件。因为执行器使这个线程保持活动一分钟,而这是一个非守护进程线程,所以整个应用程序保持活动一分钟

这只会影响在滚动后立即退出的应用程序


更新2016-12-26:此问题已得到解决。从2.8开始,默认情况下,非守护进程线程的keepAliveTime更短(1秒)

您好@sazzad,我接受这个答案,因为它解决了这个问题,但我想知道您是否可以在这个主题上做一些扩展。你知道,我总是使用log4j和logback,而且我从来没有明确地“关闭”过日志系统,所以我对这个特性有点惊讶。提前发送Thx。您可以查看此答案以及此处解决的log4j2 jira问题。我试图理解为什么我的答案被否决了。
<Policies>
    <OnStartupTriggeringPolicy/>
    <SizeBasedTriggeringPolicy size="5 MB"/>
</Policies>