How to properly shutdown log4j2

15,618

Solution 1

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

((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


Update:

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

Solution 2

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 ShutdownCallbackRegistry and their default implementation named DefaultShutdownCallbackRegistry. This implementation register itself as a shutdown hook to the JVM, with Runtime.getRuntime().addShutdownHook().

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

Proposed solution

So, what I did to fix this 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, 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.

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:

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.

Solution 3

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

To enable it, add such a dependency to your 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

Share:
15,618
user671731
Author by

user671731

Updated on June 08, 2022

Comments

  • user671731
    user671731 almost 2 years

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

  • Andrea Richiardi
    Andrea Richiardi almost 8 years
    It looks like version 2.6 adds back a proper manual .shutdown, can anyone confirm? It does not really work here
  • jansohn
    jansohn over 5 years
    And you should add shutdownHook="disable" to your log4j2.xml to disable the automatic shutdown hook.
  • ruakh
    ruakh about 4 years
    Note that the question is specifically about the case where "one is not running inside a web application" [emphasis mine].
  • leokom
    leokom almost 4 years
    you're right @ruakh anyway leaving the answer here because some people consider it useful for their cases....