How to properly shutdown log4j2
Asked Answered
C

3

13

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

Centrosome answered 16/9, 2014 at 19:40 Comment(0)
F
19

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

Fleta answered 17/9, 2014 at 0:15 Comment(2)
And you should add shutdownHook="disable" to your log4j2.xml to disable the automatic shutdown hook.Herodotus
@Herodotus can you tell me what should be added to disable shutdownhook if I am using log4j2.properties?Etymologize
C
9

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.

Candiscandle answered 3/3, 2015 at 15:19 Comment(1)
It looks like version 2.6 adds back a proper manual .shutdown, can anyone confirm? It does not really work hereCharlean
R
9

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

Rolypoly answered 13/10, 2015 at 9:1 Comment(2)
Note that the question is specifically about the case where "one is not running inside a web application" [emphasis mine].Microphysics
you're right @Microphysics anyway leaving the answer here because some people consider it useful for their cases....Rolypoly

© 2022 - 2024 — McMap. All rights reserved.