java 如何使用 Log4j2 登录关闭挂钩?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17400136/
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
How to log within shutdown hooks with Log4j2?
提问by Martin
Log4j2 also uses shutdown hooks to end it's services. But of course I want to log throughout the whole lifecycle of my application - shutdown included. With Log4j this was no problem. Now it seems to be impossible. Logging shuts down, while my application is still working on it. Has anyone some hope for me?
Log4j2 还使用关闭钩子来结束它的服务。但当然,我想在我的应用程序的整个生命周期中进行日志记录 - 包括关闭。使用 Log4j 这没有问题。现在看来是不可能了。日志记录关闭,而我的应用程序仍在处理它。有人对我有希望吗?
Best regards Martin
最好的问候马丁
回答by Chomeh
As of 2.0-beta9 this is now configurable in xml
从 2.0-beta9 开始,现在可以在 xml 中进行配置
<configuration ... shutdownHook="disable">
Considering its now disabled, I guess I need to manually shutdown the logging system at the end of my shutdown hook. However I couldn't find a means thorough the external interface, only in the internal api
考虑到它现在已禁用,我想我需要在关闭挂钩结束时手动关闭日志记录系统。但是我无法通过外部接口找到一种方法,只能在内部 api 中找到
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.LoggerContext;
...
public static void main(String[] args) {
final AnnotationConfigApplicationContext springContext = new AnnotationConfigApplicationContext(AppConfig.class)
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
//shutdown application
LOG.info("Shutting down spring context");
springContext.close();
//shutdown log4j2
if( LogManager.getContext() instanceof LoggerContext ) {
logger.info("Shutting down log4j2");
Configurator.shutdown((LoggerContext)LogManager.getContext());
} else
logger.warn("Unable to shutdown log4j2");
}
});
//more application initialization
}
回答by DjDCH
I basically just answered the same question and I tough I'll share my answer here. I encourage you to read the complete answer available here. I'll try to provide a summary here and adapt my answer to the current context.
我基本上只是回答了同样的问题,我会在这里分享我的答案。我鼓励您阅读此处提供的完整答案。我将尝试在此处提供摘要,并根据当前情况调整我的答案。
In the first version, Log4j was providing an API to manually call the shutdown procedure. For reasons we don't have the knowledge of, it was removed from the second version. Now, the right way of doing it (according to the none-existent documentation), is to provide your own implementation of the ShutdownCallbackRegistry
interface, which is responsible of the shutdown procedure.
在第一个版本中,Log4j 提供了一个 API 来手动调用关闭过程。由于我们不知道的原因,它已从第二个版本中删除。现在,正确的做法(根据不存在的文档)是提供您自己的ShutdownCallbackRegistry
接口实现,该接口负责关闭程序。
Proposed solution
建议的解决方案
What I did to fix this issue is that I implemented my own version of the ShutdownCallbackRegistry
interface. It mostly does the same things the default implementation does, but instead of registering itself as a shutdown hook to the JVM, it wait until it's invoked manually.
我为解决这个问题所做的是实现了我自己的ShutdownCallbackRegistry
界面版本。它主要做与默认实现相同的事情,但它不是将自己注册为 JVM 的关闭挂钩,而是等到它被手动调用。
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上找到完整的解决方案和说明,并在您自己的项目中使用它。基本上,最后,你只需要在你的应用程序中做这样的事情:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
try {
// Do your usual shutdown stuff here that need logging
} finally {
// Shutdown Log4j 2 manually
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. I'll be glad to hear feedback from you, either if you find this solution appropriate or not.
我不能毫无疑问地说这是完美的解决方案,我的实施是完美的,但我试图以正确的方式做到这一点。无论您是否认为此解决方案合适,我都会很高兴听到您的反馈。