How to log within shutdown hooks with Log4j2?

前端 未结 2 1645
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-01 14:26

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

相关标签:
2条回答
  • 2020-12-01 14:55

    As of 2.0-beta9 this is now configurable in 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

    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
    }
    

    Update:

    There is LogManager.shutdown() method since log4j version 2.6

    0 讨论(0)
  • 2020-12-01 14:55

    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.

    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.

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

    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.

    0 讨论(0)
提交回复
热议问题