在一个类配置中设置log4j.rootLogger = OFF将导致另一个类中的日志崩溃

时间:2015-06-06 21:30:30

标签: java logging log4j

在一个类配置中设置log4j.rootLogger = OFF会导致另一个类无法记录。 我有两个示例类:LogCrasher和MainLogger。这两个类配置为记录一些测试日志。每个类都有自己的配置文件。 LogCrasher是从MainLogger调用的。当LogCrashers log4j配置文件中的log4j.rootLogger设置为INFO,WARN ...日志记录没有问题,但是如果我们将其设置为OFF,那么MainLogger将不再输出日志。 如何解决这个问题,将一个类记录器与另一个记录器隔离开来。

MainLogger.java

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class MainLogger {
    private static String LOG_PROPS = "mainlogger.properties";
    final static Logger logger = Logger.getLogger(MainLogger.class);

    static {
        PropertyConfigurator.configureAndWatch(LOG_PROPS);
    }

    public static void main(String[] args) {
        MainLogger mainLogger = new MainLogger();
        try {
            mainLogger.doLogging();
        } catch (Throwable t) {
            logger.error(t.getMessage(), t);
        }
    }

    public void doLogging() {
        logger.info("Before calling log crasher.");
        printTestLog();

        new Thread(new Runnable() {

            @Override
            public void run() {
                LogCrasher logCrasher = new LogCrasher();
                logCrasher.printTestLog();
            }
        }).start();

        logger.info("After calling log crasher.");

        printTestLog();
    }

    private void printTestLog() {
        int counter = 0;
        while (++counter < 5) {
            logger.info("Counter: " + counter);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                logger.info("printTestLog sleeper thread interupted: " + e.getMessage());
            }
        }
    }
}

LogCrasher.java

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class LogCrasher {
    private static String LOG_PROPS = "logcrasher.properties";
    final static Logger logger = Logger.getLogger(LogCrasher.class);

    static {
        PropertyConfigurator.configureAndWatch(LOG_PROPS);
    }

    public void printTestLog() {
        int counter = 0;
        while (++counter < 5) {
            logger.info("Counter: " + counter);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                logger.info("printTestLog sleeper thread interupted: " + e.getMessage());
            }
        }
    }
}

logcrasher.properties

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

# Redirect log messages to console
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{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Rirect log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logcrasher.log
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

mainlogger.properties

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

# Redirect log messages to console
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{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Rirect log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=mainlogger.log
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

2 个答案:

答案 0 :(得分:0)

//Declare Variables// var userInput; var inputArray; //Create array of objects// var inputArray = []; //Get Input// var userInput = prompt("Enter numbers"); //transfer input to storage// inputArray = userInput; //Display new storage unit// alert(inputStorage); //Take one element off user input// userInput.pop(); //Disply new input data// alert(userInput); 使用callfunction("event1"); // call this function on execution of event 1 callfunction("event2"); // call this function one execution of event 2 var eventObj = { event1: false, event2: false }; // event object // function function callfunction(eventFrom) { if(eventFrom === "event1") { eventObj.event1 = true; } else { eventObj.event2 = true; } // if condition will be true only when both the events are fired if(eventObj.event2 === true && eventObj.event1 === true) { // callback function } } 方法...因此,如果您在1个类中重新加载新的log4 framework,则同一factory/singleton中的所有类都应该看到config 1}}好像它是1真class loader

您需要做的是在config级别封装所需的日志记录行为,并在调用live config时看到效果。使用较新版本的package/class,您可以使用Logger.getLogger()调用apache log4j来获取LogManger.getLogger()的记录器(可以在所有类文件中轻松定义)。

然后,由于您可以拥有不同系列的no argscurrent class,以及将appender设置为通过不同的记录器级联,因此您不需要超过1个配置文件。

希望有所帮助!

答案 1 :(得分:0)

您无法像这样定义2个log4j属性文件。 Log4j框架将加载并仅考虑一个,它将首先在类路径中找到。

现在对于问题的解决方案部分,你不能在类级别上有单独的日志记录方案,但是你可以在包级别有单独的日志记录方案。
现在考虑你的2个类在不同的包中,你可以使用如下的log4j.properties log4j.logger.com.stackoverflow.meta将适用于com.stackoverflow.meta包中的所有类,log4j.logger.com.stackoverflow.code适用于com.stackoverflow.code包中的所有类。

就像这样,您现在可以控制包级别的日志记录。

log4j.logger.com.stackoverflow.meta=OFF, file, stdout
log4j.logger.com.stackoverflow.code=DEBUG, file, stdout

# Redirect log messages to console
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{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Rirect log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=mainlogger.log
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n