Reputation: 491
We have implemented a custom configuration factory in order to programmatically configure Log4J2:
ConfigurationFactory.setConfigurationFactory(new MyConfigurationFactory());
The initial configuration works correctly.
We have certain listeners in our code that triggers a global 'refresh configuration' event. When this happens we need to completely reconfigure Log4J.
I have tried a number of options to tell Log4J 'reconfigure', but none of them are adequately recreating the Appenders with new configuration.
Here's the closest thing I have found, but it doesn't work for Appender config:
ConfigurationFactory.setConfigurationFactory(new MyConfigurationFactory());
LoggerContext ctx = (LoggerContext) LogManager.getContext();
ctx.reconfigure();
ctx.updateLoggers();
How can I trigger off a global reconfigure event in Log4J2 so that it will drop its entire configuration and then configure itself in full?
Edit: After further investigation and debugging, it appears that the logger configuration is not being updated either. The initial level set for the logger remains unchanged. A new instance of the immutable class org.apache.logging.log4j.core.Logger.PrivateConfig
is not constructed.
Edit 2: I have managed to implement a solution that works, however the implementation is terrible and I can only assume this works by accident not by design:
LoggerContext ctx = (LoggerContext) ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).getContext();
for(org.apache.logging.log4j.core.Logger l : ctx.getLoggers())
{
l.getContext().onChange((Reconfigurable) ctx.getConfiguration());
}
ctx.reconfigure();
My work is to implement a common framework to support programmatic reconfiguration, so it is important that the implementation is not brittle/flawed. I am hoping there is a correct way to reconfigure Log4J2 in full, rather than code like this that I would consider a hack.
Edit 3: Solution: As per the accepted answer below I have changed my code to the following:
ConfigurationFactory configFactory = new MyConfigurationFactory();
ConfigurationFactory.setConfigurationFactory(configFactory);
org.apache.logging.log4j.core.LoggerContext ctx = (org.apache.logging.log4j.core.LoggerContext) LogManager
.getContext(false);
ctx.start(configFactory.getConfiguration(ConfigurationSource.NULL_SOURCE));
Upvotes: 5
Views: 5541
Reputation: 9141
If you want a complete reconfiguration then use your configuration factory to create a new one. Then use the Configurator class to replace the configuration or call setConfiguration on the LoggerContext.
Upvotes: 2