Log4j : Creating/Modifying appenders at runtime, l

2019-01-19 01:04发布

I want to create and enable an appender for a particular method call MyMethod(), whose log output is supposed to go to a file present at "logFilePath".

I do not want to include this appender in the xml configuration file, so I thought to create it at run time.

First, I tried to modify the logger properties at runtime and then calling activateOptions, eg. setting level to DEBUG before and setting it to Off in the finally block, so that output is logged only while the method is in use. That didn't work.

My problem here is that appender recreates a file everytime, and does not append to the same file. This is inspite of setAppend being true.

I am not very familiar with log4j, so please feel free to suggest an alternative approach. The following is sample code to explain what I am trying.

private static FileAppender createNewAppender(String logFilePath) {
    FileAppender appender = new FileAppender();
    appender.setName("MyFileAppender");
    appender.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
    appender.setFile(logFilePath);
    appender.setAppend(true);
    appender.setThreshold(Level.INFO);
    appender.activateOptions();
    Logger.getRootLogger().addAppender(appender);
    return appender;
}

private static void removeAppender() {
    Logger.getRootLogger().removeAppender(fileAppender) ; // ("MyFileAppender");
}

I call the above methods in the following way:

private static FileAppender fileAppender = null;

private static void myMethod(String logFilePath) {        
    try {
        fileAppender = createNewAppender();
        someOperation();
    }
    finally {
        removeAppender();
        fileAppender=null; 
    }
}

标签: java log4j
2条回答
Melony?
2楼-- · 2019-01-19 01:34

I do the following from scala (basically the same):

Set my root logging level to TRACE but set the threshold on my global appenders to info.

# Root logger option
log4j.rootLogger=TRACE, file, stdout

# log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log.log
log4j.appender.file.MaxFileSize=100MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{HH:mm:ss} %m%n
log4j.appender.file.Threshold=INFO

# log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %m%n
log4j.appender.stdout.Threshold=INFO

Then in the class I want to log:

private def set_debug_level(debug: String) {
  import org.apache.log4j._
  def create_appender(level: Level) {
    val console_appender = new ConsoleAppender()
    val pattern = "%d %p [%c,%C{1}] %m%n"
    console_appender.setLayout(new PatternLayout(pattern))
    console_appender.setThreshold(level)
    console_appender.activateOptions()
    Logger.getRootLogger().addAppender(console_appender)
  }
  debug match {
    case "TRACE" => create_appender(Level.TRACE)
    case "DEBUG" => create_appender(Level.DEBUG)
    case _ => // just ignore other levels
  }
}

So basically, since I set the threshold of my new appender to TRACE or DEBUG it will actually append. If I change the root to another level it will not log a lower level.

查看更多
Ridiculous、
3楼-- · 2019-01-19 01:41

very easy just create a method and add this

String targetLog="where ever you want your log"

FileAppender apndr = new FileAppender(new PatternLayout("%d %-5p [%c{1}] %m%n"),targetLog,true);    
logger.addAppender(apndr);
logger.setLevel((Level) Level.ALL);

then in any method you need to log just do this: logger.error("your error here");

查看更多
登录 后发表回答