13

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

4

3 回答 3

15

对此没有公共 API,但您可以使用

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

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


更新:

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

于 2014-09-17T00:15:37.207 回答
9

解释和背后的故事

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

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

建议的解决方案

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

您可以在GitHub/DjDCH/Log4j-StaticShutdown上找到完整的解决方案和说明,并在您自己的项目中使用它。基本上,最后,你只需要在你的应用程序中做这样的事情:

StaticShutdownCallbackRegistry.invoke();

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

于 2015-03-03T15:19:59.430 回答
8

Log4j-Web库是在 Web 应用程序中正确清理资源的首选方式。

要启用它,请将这样的依赖项添加到您的 pom.xml

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
    <version>${log4j2.version}</version>
    <scope>runtime</scope>
</dependency>

它将在 Servlet 3.* 环境中“开箱即用”地工作。如果您使用的是较旧的 Servlet 规范,请在此处获得如何为 log4j2 启用正确清理的详细信息: https ://logging.apache.org/log4j/2.x/manual/webapp.html

于 2015-10-13T09:01:06.397 回答