Hello StackOverflow社区,
我正在编写一个多线程应用程序,其中我需要使用log4j为每个线程输出日志文件。理想情况下,我希望为每个线程运行一个单独的日志实例。我正在讨论如何解决这个问题。因为每个日志实例的文件输出位置不同,所以我需要为每个实例更新log4j.appender.BrokerFile.File=
属性。截至目前我正在尝试创建一个新的Logger,将新属性设置为一个属性对象,并使用PropertyConfigurator.configure(log4jProperties);
将新属性加载到我新创建的Logger对象中,同时创建新的Logger实例,新实例似乎无法识别新属性。我是否需要为每个新的Logger实例创建一个新的FileAppender?
public class Broker implements Runnable{
private Settings ss; //The Settings object associated with this broker.
private String loggerName = null;
private Logger log = null;
private Properties log4jProperties = new Properties();
}
//Constructor
public Broker(Settings ss){
this.ss = ss;
}
public void run() {
loggerName = ss.getBrokerName() + "_Logger";
log = Logger.getLogger(loggerName);
log4jProperties.setProperty("log4j.loggerName", "DEBUG, FILE");
log4jProperties.setProperty("log4j.appender.FILE","org.apache.log4j.FileAppender");
log4jProperties.setProperty("log4j.appender.FILE.File", "C:/Logz/"+loggerName+".out");
log4jProperties.setProperty("log4j.appender.FILE.ImmediateFlush", "true");
log4jProperties.setProperty("log4j.appender.FILE.Threshold", "DEBUG");
log4jProperties.setProperty("log4j.appender.FILE.Append", "FALSE");
log4jProperties.setProperty("log4j.appender.FILE.layout", "org.apache.log4j.PatternLayout");
log4jProperties.setProperty("log4j.appender.FILE.layout.conversionPattern", "%m%n");
PropertyConfigurator.configure(log4jProperties);
log.debug("This is a debug message");
// This will be set to true as long as the Broker is running
while(isRunnable){
//Listen for and process files
}
}
这是控制台输出。如您所见,正在创建新的记录器实例,但无法识别新属性。
log4j:WARN No appenders could be found for logger (Broker1_Logger).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
log4j:WARN No appenders could be found for logger (Broker2_Logger).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
log4j:WARN No appenders could be found for logger (Broker3_Logger).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
每个经纪人都会这样做。有没有办法直接将我的配置设置应用于Logger对象?例如,像 的登录 .PropertyConfigurator.configure(log4jproperties); 必须有一种方法将配置设置应用于创建的每个记录器对象。
谢谢,
吉姆
答案 0 :(得分:1)
似乎需要为每个新实例创建一个新的appender,因为每个实例都需要打印到不同的文件输出位置。我通过创建一个带有必要参数的generateLogger()方法来解决这个问题,以创建新的记录器和appender programmitcally。如果您注意到第一个参数包含父记录器的名称。如果我在新的记录器名称中包含它,它将继承其父级的属性,该属性在master.properties文件中配置,反之亦然。例如,如果我的父记录器是“Broker”而我的记录器名称是“Broker1”,那么完整的loggerName将是“Broker.Broker1”。这样,我可以在一个日志文件中跟踪所有代理,同时在每个代理的单独文件输出位置中具有单独的日志文件。更不用说,这种方法可以使用不同的父记录器重复使用许多不同类型的日志。虽然如果您选择,甚至不需要父记录器。如果您选择没有父Logger,只需从方法中删除它并忽略我的master.properties文件。
public Logger generateLogger(String parent, String name, String logDirectory, String filePattern, String fileThreshold) {
// TODO Auto-generated method stub
//Create Logger
String loggerName = parent + "." + name;
Logger log = Logger.getLogger(loggerName);
//Create Logging File Appender
RollingFileAppender fileApp = new RollingFileAppender();
fileApp.setName("Broker." + loggerName + "_FileAppender");
fileApp.setFile(logDirectory +"/"+ name+".log");
fileApp.setLayout(new PatternLayout(filePattern));
fileApp.setThreshold(Level.toLevel(fileThreshold));
fileApp.setAppend(true);
fileApp.activateOptions();
log.addAppender(fileApp);
return log;
}
以下是我的master.properties文件中的Broker记录器配置以供参考。
log4j.logger.Broker=DEBUG, BrokerFile
# Broker Appenders
# Broker File Appender
log4j.appender.BrokerFile=org.apache.log4j.RollingFileAppender
log4j.appender.BrokerFile.File=C:/Documents and Settings/gr2cher/My Documents/KTLO/Java/CMInbound/BrokerLogs/Logs/Broker.log
log4j.appender.BrokerFile.MaxFileSize=1MB
log4j.appender.BrokerFile.MaxBackupIndex=1
log4j.appender.BrokerFile.layout=org.apache.log4j.PatternLayout
log4j.appender.BrokerFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.appender.BrokerFile.threshold=DEBUG