如何使用Log4j2在关机钩子内记录日志?建议的解决方案

2022-09-01 18:49:08

Log4j2还使用关闭钩子来结束它的服务。但是,当然,我希望在应用程序的整个生命周期内进行记录 - 包括关闭。使用Log4j,这没有问题。现在看来这是不可能的。日志记录将关闭,而我的应用程序仍在处理它。有人对我抱有希望吗?

最好的问候马丁


答案 1

从2.0-beta9开始,现在可以在xml中配置。

<configuration ... shutdownHook="disable">

考虑到它现在被禁用,我想我需要在关闭钩子结束时手动关闭日志记录系统。但是,我无法通过外部接口找到方法,只能在内部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
}

更新:

log4j版本2.6以来有LogManager.shutdown()方法


答案 2

我基本上只是回答了同样的问题,我很难在这里分享我的答案。我鼓励您阅读此处提供的完整答案。我将尝试在此处提供摘要,并根据当前上下文调整我的答案。

在第一个版本中,Log4j提供了一个API来手动调用关闭过程。由于我们不了解的原因,它已从第二个版本中删除。现在,正确的方法(根据不存在的文档)是提供您自己的 ShutdownCallbackRegistry 接口的实现,该接口负责关闭过程。

建议的解决方案

我解决这个问题的方法是,我实现了我自己的接口版本。它主要执行与默认实现相同的操作,但不是将自身注册为 JVM 的关闭挂钩,而是等到手动调用它。ShutdownCallbackRegistry

您可以在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();
        }
    }
}));

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


推荐