如何正确关闭 log4j2背后的解释和故事建议的解决方案

如果一个应用程序没有在Web应用程序内运行,那么关闭Log4j2的正确方法是什么?我只看到一个noop LogManager.shutdown()


答案 1

没有用于此目的的公共 API,但您可以使用

((LifeCycle) LogManager.getContext()).stop();

如果您有兴趣为此提供公共API,请在此处投票或添加评论:https://issues.apache.org/jira/browse/LOG4J2-124


更新:

在Log4j 2.5中,您可以调用 .使用Log4j 2.6,您可以调用.Configurator.shutdown()LogManager.shutdown()


答案 2

背后的解释和故事

Log4j 2内部使用的是他们所谓的OffinRegistrationStrategy。它由一个类组成,该类注册一个或多个关机回调,这些回调将在适当的时间调用。它们提供名为 ShutdownCallbackRegistry 的接口,以及它们的默认实现名为 DefaultShutdownCallbackRegistry。此实现将自身注册为 JVM 的关机挂钩,使用 .Runtime.getRuntime().addShutdownHook()

根据Log4j 2错误跟踪器(LOG4J2-868LOG4J2-658)上的一些问题,正确的方法是提供您自己的接口实现。由于没有公共API来关闭Log4j 2,这是唯一真正有效的存档方式。ShutdownCallbackRegistry

建议的解决方案

因此,我为解决此问题所做的是,我实现了自己的接口版本。它主要执行与默认实现相同的操作,但不是将自己注册为关闭钩子,而是等到手动调用它。通过在静态字段中保留对象的实例,可以在内部实现这一点。然后,您只需要调用单个静态方法来启动关闭过程,因此我将其命名为StaticShutdownCallbackRegistryShutdownCallbackRegistry

您可以在GitHub / DjDCH / Log4j-StaticShutdown上找到完整的解决方案和说明,并在您自己的项目中使用它。基本上,最后,您只需要在应用程序中执行如下操作:

StaticShutdownCallbackRegistry.invoke();

我不能毫无疑问地说这是完美的解决方案,我的实现是完美的,但我试图以正确的方式做到这一点(根据关于它不存在的文档)。我很乐意听到您的反馈,无论您是否认为此解决方案合适。


推荐