java 如何正确关闭log4j2

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25877102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 08:50:19  来源:igfitidea点击:

How to properly shutdown log4j2

javalogginglog4jlog4j2application-shutdown

提问by user671731

If one is not running inside a web application, what is the proper way to shutdown Log4j2? I only see a noop LogManager.shutdown()

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

回答by Remko Popma

There is no public API for this, but you can use

没有为此提供公共 API,但您可以使用

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

If you have an interest in having a public API for this, please vote for or add a comment here: https://issues.apache.org/jira/browse/LOG4J2-124

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



Update:

更新:

In Log4j 2.5 you can call Configurator.shutdown(). With Log4j 2.6 you can call LogManager.shutdown().

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

回答by DjDCH

Explanation and story behind

解释和背后的故事

What Log4j 2 use internally is what they call a ShutdownRegistrationStrategy. It consist of a class that register one or many shutdown callback(s) that would be called at the appropriate time. They provide interface named ShutdownCallbackRegistryand their default implementation named DefaultShutdownCallbackRegistry. This implementation register itself as a shutdown hook to the JVM, with Runtime.getRuntime().addShutdownHook().

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

According to some issues on the Log4j 2 bug tracker (LOG4J2-868and LOG4J2-658), the right way would be to provide your own implementation of the ShutdownCallbackRegistryinterface. Since there is no public API to shutdown Log4j 2, this is the only real and valid way to archive this.

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

Proposed solution

建议的解决方案

So, what I did to fix this is that I implemented my own version of the ShutdownCallbackRegistryinterface. It mostly does the same things the default implementation does, but instead of registering itself as a shutdown hook, it wait until it's invoked manually. That is made possible internally by keeping the instance of the object in a static field. You then only have to call single static method to launch the shutdown procedure, hence why I named it the StaticShutdownCallbackRegistry.

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

You can find the complete solution and instructions on GitHub/DjDCH/Log4j-StaticShutdownand use it in you own projects. Basically, at the end, you only have to do something like this in your application:

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

StaticShutdownCallbackRegistry.invoke();

I can't say without any doubt that this is the perfect solution and that my implementation is perfect, but I tried to do it the right way (according to the none-existent documentation about it). I'll be glad to hear feedback from you, either if you find this solution appropriate or not.

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

回答by leokom

Log4j-Weblibrary is the preferred way to properly clean-up resources in Web-application.

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

To enable it, add such a dependency to your pom.xml

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

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

It will work 'out-of-the box' in Servlet 3.* environment. If you're using older Servlet specification, details how to enable proper cleaning for log4j2 are available here: https://logging.apache.org/log4j/2.x/manual/webapp.html

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