java - 使用log4j创建多个日志实例以在不同位置输出日志文件

标签 java multithreading log4j

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 对象?例如,类似的东西 log.PropertyConfigurator.configure(log4jproperties); 必须有一种方法将配置设置应用于创建的每个记录器对象。

谢谢,

吉姆

最佳答案

似乎有必要为每个新实例创建一个新的附加程序,因为每个实例都需要打印到不同的文件输出位置。我通过创建一个包含必要参数的generateLogger()方法来解决这个问题,以编程方式创建新的记录器和附加器。如果您会注意到第一个参数包含父记录器的名称。如果我将其包含在新记录器名称中,它将继承其父记录器的属性,该属性在我的 master.properties 文件中配置,反之亦然。例如,如果我的父记录器是“Broker”并且我的记录器名称是“Broker1”,则完整的记录器名称将为“Broker.Broker1”。这样,我可以在一个日志文件中跟踪所有代理,同时在每个代理各自单独的文件输出位置中拥有单独的日志文件。更不用说,此方法可以与使用不同父记录器的许多不同类型的日志一起重复使用。尽管如果您选择的话,父记录器甚至不是必需的。如果您选择不使用父记录器,只需从方法中将其删除并忽略我的 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

关于java - 使用log4j创建多个日志实例以在不同位置输出日志文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18664903/

相关文章:

java - Hibernate 不删除外键行(而是将其设置为 NULL)

python - 主线程退出后如何让守护线程保持事件状态?

ruby - 你将如何在 ruby​​ 2.0 中实现与信号的保存线程协作?

c# - 任务并行库 (TPL) 中的线程同步

java - LOG4J2 - 如何以编程方式创建文件附加程序?

c++ - log4cpp - 未处理的异常和访问冲突

java - 从现有子集创建子集的有效方法?

java - 从 wicket 消息中设置 html 元素属性

java - Enum 类型不是通用的;它不能用参数 <RestClient.RequestMethod> 参数化

java - log4j 日志未写入文件的问题