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 no problem. Now it seems to be impossible. Logging shuts down, while my application is still working on it. Has anyone some hope for me?
Best regards Martin
From the surface, using a shutdown hook is downright straightforward. All we have to do is simply write a class that extends the java. lang. Thread class, and provide the logic that we want to perform when the VM is shutting down, inside the public void run() method.
You can set a logger's level with the class Configurator from Log4j Core. BUT be aware that the Configurator class is not part of the public API. If you wish to change the root logger level, do something like this : LoggerContext ctx = (LoggerContext) LogManager.
This concept is known as Logger Hierarchy. Logger Hierarchy is made up of set of LoggerConfig objects with a parent-child relationship. The topmost element in every Logger Hierarchy is the Root Logger. If Log4j2 doesn't find the configuration file, only Root Logger will be used for logging with logging level as ERROR.
Community support: Log4j 1. x is not actively maintained, whereas Log4j 2 has an active community where questions are answered, features are added and bugs are fixed. Automatically reload its configuration upon modification without losing log events while reconfiguring.
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
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.
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.
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