If one is not running inside a web application, what is the proper way to shutdown Log4j2? I only see a noop LogManager.shutdown()
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()
.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With