ReConfiguring_Log4j_Appenders_at_Runtime

Quick Profile

Alex Ooi Profile Picture
Hometown: Melbourne, Australia
Specializations: Java, Ruby on Rails
University: Software Engineering & Economics, Melbourne University
High School: VCE, Melbourne High School
Links:
 

Popular Articles

Wednesday, July 20, 2011

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!

The org.apache.log4j.LogManager

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

Bat Pig!!!
Posted by Ultime Bat Pig on Tuesday, August 23, 2011 at 03:56 PM
Pig pig pig
Posted by SuperPig Pig on Tuesday, August 23, 2011 at 03:58 PM

Add a Comment

*
*
You must answer the following simple maths question before your comment will be accepted.
*