Log4J学习【四】复杂一点的例子二

来源:互联网 发布:南京java公司招聘 编辑:程序博客网 时间:2024/04/30 02:15
上面我们演示了一个稍微复杂一点的例子,在那个例子中,我们使用了不同的日志打印级别,并且控制了打印级别,但是上面的例子仍然是对于一个类的日志控制,我们在这个例子中,来看看,控制不同模块的日志打印。
在上面的例子中,我们加入一个新的类,这个类放在一个额外的包中:
package cd.itcast.core;

import org.apache.log4j.Logger;

import cd.itcast.log4j.Configure;

public class LogicProcessor {
    private static Logger log=Logger.getLogger(LogicProcessor.class);

    public void init(Configure conf){
        log.info("init logic processor using conf");
    }

    public void process(){
        log.info("process some logic");
        log.debug("process some detail logic");
    }
}


在这个类中,我们创建了一个模拟某种核心处理器的类,这个类放在了cd.itcast.core包里面,然后在这个类里面使用不同的日志级别打印了一些日志。
然后我们来完成一个测试:
package cd.itcast.log4j;

import org.apache.log4j.BasicConfigurator;
import org.junit.Test;

import cd.itcast.core.LogicProcessor;

public class LogTest3 {

    @Test
    public void testLog(){
        BasicConfigurator.configure();

        Configure conf=new Configure();
        conf.config();

        LogicProcessor processor=new LogicProcessor();
        processor.init(conf);
        processor.process();
    }
}

注意,这个测试我们仍然是放在cd.itcast.log包中的,这个没有任何关系。在这个测试中,我们综合使用到了之前的Configure类和新的LogicProcessor类来完成一些业务逻辑。同样,我们先简单使用BasicConfigurator.configure()完成基础设置。运行测试,输出:
0 [main] INFO cd.itcast.log4j.Configure  - using default db.properties
0 [main] INFO cd.itcast.log4j.Configure  - using config file in classpath:db.properties
15 [main] DEBUG cd.itcast.log4j.Configure  - load properties file success
31 [main] DEBUG cd.itcast.log4j.Configure  - [properties] driverClass : com.mysql.jdbc.Driver
31 [main] DEBUG cd.itcast.log4j.Configure  - [properties] url : jdbc:mysql:///log4j
31 [main] DEBUG cd.itcast.log4j.Configure  - [properties] password : admin
31 [main] DEBUG cd.itcast.log4j.Configure  - [properties] username : log4j
31 [main] INFO cd.itcast.core.LogicProcessor  - init logic processor using conf
31 [main] INFO cd.itcast.core.LogicProcessor  - process some logic
31 [main] DEBUG cd.itcast.core.LogicProcessor  - process some detail logic

    观察输出,两个类里面的所有的日志都输出了,根据上一个例子,我们基本能够猜到,默认情况下,rootLogger的日志级别被设置为了Level.DEBUG。下面,我们来模拟一个场景。假如现在我们已经完成了cd.itcast.log.Configure类的详细测试,我们只想这个类做WARN级别之上的日志输出,但是现在我们还没有确定LogicProcessor是否正常运行,所以对于LogicProcessor类我们要做DEBUG级别的日志。
    怎么控制这个输出?其实我们根据前一个例子解释的Logger的继承的体系结构,我们能有两种方式来完成这个目的。
1,设置rootLogger日志级别为DEBUG;设置cd.itcast.log4j.Configure日志级别为WARN。
2,设置rootLogger日志级别为WARN;设置cd.itcast.core.LogicProcessor日志级别为DEBUG。
    我们随意选择一种模式,比如第二种,那么,修改我们的代码:
import org.junit.Test;

import cd.itcast.core.LogicProcessor;

public class LogTest3 {

    @Test
    public void testLog(){
        BasicConfigurator.configure();
        Logger.getRootLogger().setLevel(Level.WARN);
        Logger.getLogger("cd.itcast.core.LogicProcessor").setLevel(Level.DEBUG);

        Configure conf=new Configure();
        conf.config();

        LogicProcessor processor=new LogicProcessor();
        processor.init(conf);
        processor.process();
    }
}

    再次运行测试,输出:
0 [main] INFO cd.itcast.core.LogicProcessor  - init logic processor using conf
0 [main] INFO cd.itcast.core.LogicProcessor  - process some logic
0 [main] DEBUG cd.itcast.core.LogicProcessor  - process some detail logic


    达到我们的目的。我们回过头来看看我们到底做了些什么。加了两行代码,第一行代码大家应该熟悉了,设置rootLogger的日志级别为WARN,那么在该rootLogger体系结构中的cd.itcast.log.Configure和cd.itcast.core.LogicProcessor默认日志级别都变成了WARN。接着第二行代码,我们使用Logger.getLogger()方法,传入cd.itcast.core.LogicProcessor参数,就得到了和LogicProcessor类绑定的那个Logger实例。注意这里,通过Logger.getLogger(“cd.itcast.core.LogicProcessor”)得到的Logger实例和我们在LogicProcessor类中使用Logger.getLogger(LogicProcessor.class)得到的Logger实例是一个实例。换句话说,在一个rootLogger体系结构中,绑定到同一个名字的Logger实例只会有一份。接着,我们再设置这个Logger的日志记录级别为Level.DEBUG,那么LogicProcessor绑定的Logger实例就不再继承rootLogger的日志记录级别了。所以,能正常打印。

    通过这段代码,我们可以再次看到这个rootLogger的继承体系结构和继承的关系。当然,Log4J远远不止如此。
    假如现在我们在cd.itcast.log包中和cd.itcast.core包中,不止一个类,换句话说,我现在想让cd.itcast.log包及其子包中的类的日志级别为WARN,而让cd.itcast.core包及其子包中的所有类的日志级别为DEBUG,又该怎么做呢?可能这种情况才是我们在现实应用当中会遇到的吧。其实非常简单,我们只需要改一句代码:
@Test
public void testLog(){
    BasicConfigurator.configure();
    Logger.getRootLogger().setLevel(Level.WARN);
    Logger.getLogger("cd.itcast.core").setLevel(Level.DEBUG);

    Configure conf=new Configure();
    conf.config();

    LogicProcessor processor=new LogicProcessor();
    processor.init(conf);
    processor.process();
}


    再次运行测试,输出:
0 [main] INFO cd.itcast.core.LogicProcessor  - init logic processor using conf
0 [main] INFO cd.itcast.core.LogicProcessor  - process some logic
0 [main] DEBUG cd.itcast.core.LogicProcessor  - process some detail logic

    同样达到了目的。
    加粗的代码是不是很不可思议?我们这次不再得到cd.itcast.core.LogicProcessor绑定的Logger,而是得到cd.itcast.core包对应的Logger,是的,就是这样。当我们绑定cd.itcast.core.LogicProcessor对应的Logger的时候,实际上隐式的绑定了cd、cd.itcast、cd.itcast.core这三个Logger。所以,现在的rootLogger体系结构应该是这样:

    那么,当我设置rootLogger的日志级别为WARN,并得到cd.itcast.core绑定的Logger,设置其日志级别为DEBUG的时候,rootLogger、cd、cd.itcast、cd.itcast.log、cd.itcast.log.Configure的日志级别都是WARN,而cd.itcast.core、cd.itcast.core.LogicProcessor的日志级别为DEBUG。

    通过这个示例,我们对Logger的继承体系应该有了更深入一些的了解,也可以通过这个例子可以看出,当我们对不同级别的Logger做特定的配置的时候,会非常灵活的控制我整个系统的日志输出,这是Log4J最为强大的地方之一。
如果你曾经使用过Log4j,你也许会对上面的代码感到非常奇怪,以前不是这样用Log4J的呀,也不要慌,之后就能慢慢看到平时我们使用Log4J的方式和其使用方式后面的真正含义。
下一节,我们会从一个更高的层次来看看Log4J整个框架的体系结构。
0 0
原创粉丝点击