Just a quickie whilst I wait for my build to finish...
Re-Configuring log4j at runtime is something we don't have to do very often, however, it can on occasion be necessary. Recently, I needed to reconfigure the location of our applications log file at runtime. The actual location was configured in a custom properties file, so there was no way to easily inject this value into our log4j.xml... But if anyone who happens to read this post has a better way to do this then feel free to pipe up in the comments section!
So this is our starting point. It contains a "repository" of all the available loggers that are configured in our xml/properties file. I also have the log file path hard coded in this example, but in our application we retrieved it from a custom location beforehand
The only gotcha is that the loggers have a parent logger, and the file logger/s that we're interested in may not necessarily be in the immediate Enumeration of loggers returned by the #getAllAppenders() method. A bit of recursion is required to make sure we catch all of our configured FileAppenders...
private static void configureFileAppenders()
{
String logFilePath = "/Users/alex.ooi/blah/application.log";
configureFileAppenders(logFilePath, LogManager.getRootLogger());
for(Category logger : Collections.list(LogManager.getCurrentLoggers()))
{
configureFileAppenders(logFilePath, logger);
}
}
private static void configureFileAppenders(
String logFilePath, Category logger)
{
if (logger == null)
{
return;
}
for(Appender appender : Collections.list(logger.getAllAppenders()))
{
if (appender instanceof FileAppender)
{
FileAppender fileAppender = (FileAppender) appender;
fileAppender.setFile(logFilePath);
fileAppender.activateOptions();
}
}
configureFileAppenders(logFilePath, logger.getParent());
}
And that ensures that each of the FileAppenders are configured to the new path defined at runtime. The only thing I might add is that at the time the Root Logger wasn't being returned as part of the #getCurrentLoggers() call. So an explicit call to #getRootLogger() was required.
Comments ...