prathap
prathap

Reputation: 464

Changing Log4j file name dynamically

I am implementing Log4j in my project. I would like to log every n (say 10) log entries into new file. I tried using 'RollingFileAppender' but i think it will change log files only based on size and time.

So far i did below code:

log4j.properties

log4j.logger.ControlTable=debug, controlTable
log4j.additivity.ControlTable = false
log4j.appender.controlTable=org.apache.log4j.RollingFileAppender
log4j.appender.controlTable.File=${log4jfilename}
log4j.appender.controlTable.MaxFileSize=10MB
log4j.appender.controlTable.MaxBackupIndex=10
log4j.appender.controlTable.layout=org.apache.log4j.PatternLayout

Main

public class ControlTableLoggerConsumer {
static {
    System.setProperty("log4jfilename","d:\\control_log_1_9.json");
}
private static final Logger log = Logger.getLogger("ControlTable");
private static long logEntries = 0;
public static void main(String args[]) {
      System.out.println("Curr log file:"+logEntries+"::"+System.getProperty("log4jfilename"));
      log.info("Log entry:"+logEntries);
      logEntries++;
      if((logEntries >= 10) && ((logEntries % 10) == 0)) {
         System.out.println("going to change file name to "+"d:\\control_log_"+logEntries+"_"+(logEntries+9)+".json");
         System.setProperty("log4jfilename","d:\\control_log_"+logEntries+"_"+(logEntries+9)+".json");
      }
      if(logEntries == 1000)
         break;
}

on console i can see the file name changing for every 10 entries, but in my D drive i can see only one file with all log info.

Upvotes: 0

Views: 3840

Answers (2)

Adrian Shum
Adrian Shum

Reputation: 40036

Your solution does not seem to be a very good solution to me because:

  1. Appender is no longer transparent to your logging code
  2. It become extremely messy if you are going to log in different places, for which you need to find a common place to store that logEntries.

Consider writing your custom Appender (I bet you can mostly copy what's inside RollingFileAppender but just change the triggering criteria from file size to number of records written.

Have had a brief look in the RollingFileAppender. Seems that you can extend from it, and overwrite the subAppend() method.

public class RowCountRollingFileAppender extends FileAppender {
    // constructors
    // getter setters
    private maxEntries = 10;      // provided through config

    private currentEntries = 0;

    public void rollOver() {
        currentEntries = 0;
        super.rollOver();
    }
    protected void subAppend(LoggingEvent event) {
         super.subAppend(event);
         currentEntries++;
         if (fileName != null 
                 && qw != null 
                 && currentEntries > maxEntries) {
             rollOver();
         }
    }
}

Then you can have an appender that will roll over if either file hit max size, or it have n messages logged.

Upvotes: 0

prathap
prathap

Reputation: 464

Finally i solved this issue as below.

Properties props = new Properties(); 
    try { 
        InputStream configStream = getClass().getResourceAsStream("/log4j.properties"); 
        props.load(configStream); 
        configStream.close(); 
    } catch (IOException e) { 
        System.out.println("Errornot laod configuration file "); 
    } 
    props.setProperty("log4j.appender.controlTable.File", logFile); 
    LogManager.resetConfiguration(); 
    PropertyConfigurator.configure(props);

Now i can log into to different files dynamically. Hope it helps others as well.

Upvotes: 1

Related Questions