刚学习log4j2日志,对于里面的root和logger的继承关系比较迷惑,遂有此文
使用控制台输出不同级别的日志,并定义日志的继承关系测试
附上demo地址
示例项目使用maven作依赖管理
github源码地址:https://github.com/fizzme/log4j2-start1
<dependencies>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-apiartifactId>
<version>2.9.1version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>2.9.1version>
dependency>
dependencies>
定义Logger配置的继承
定义要输出到控制台指定的日志级别为trace
那么trace及其以上级别的日志将输出到控制台
需要做的实际上就是,将root级别的日志设置的高一些,
未在配置文件中明确设置的Logge,将会继承root Logger,日志打印按照root的appender进行
说明:
来看我们添加的配置文件log4j2.xml,以Configuration为根节点,有一个status属性(关闭自身日志输出 status=”OFF”>),这个属性表示log4j2本身的日志信息打印级别。如果把status改为TRACE再执行测试代码,可以看到控制台中打印了一些log4j加载插件、组装logger等调试信息。
1.2 、日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出。对于Loggers中level的定义同样适用。
1.3、Appender可以理解为日志的输出目的地,这里配置了一个类型为Console的Appender,也就是输出到控制台。Console节点中的PatternLayout定义了输出日志时的格式
(4)配置说明:
这里配置了两个logger,一个是com.fizzbook.log4j2
,一个是root的Logger
根据log4j的日志继承关系,com.fizzbook.log4j2.xxx.xx
表示是logger:com.fizzbook.log4j2
的子孙节点
如果不指定日志相关的日志配置LoggerConfig,就会使用父logger的
我们在getLogger以如下方式获取的LogManager.getLogger(Name);
name如果是配置中的logger的子节点,将使用父logger的appender和日志级别配置
static Logger logger = LogManager.getLogger(App.class.getName());
配置Appender
log4j的additivity属性:
它是 子Logger 是否继承 父Logger 的 输出源(appender) 的标志位。具体说,默认情况下子Logger会继承父Logger的appender,也就是说子Logger会在父Logger的appender里输出。若是additivity设为false,则子Logger只会在自己的appender里输出,而不会在父Logger的appender里输出。
在com.fizzbook.log4j2包里面创建Hello.java来测试日志
public class Hello {
static Logger logger = LogManager.getLogger(Hello.class.getName());
public boolean hello() {
logger.entry(); //trace级别的信息,单独列出来是希望你在某个方法或者程序逻辑开始的时候调用,和logger.trace("entry")基本一个意思
logger.error("Did it again!"); //error级别的信息,参数就是你输出的信息
logger.info("我是info信息"); //info级别的信息
logger.debug("我是debug信息");
logger.warn("我是warn信息");
logger.fatal("我是fatal信息");
logger.log(Level.DEBUG, "我是debug信息"); //这个就是制定Level类型的调用:谁闲着没事调用这个,也不一定哦!
logger.exit(); //和entry()对应的结束方法,和logger.trace("exit");一个意思
return false;
}
public static void main(String[] args) {
Hello hello = new Hello();
logger.info( "Hello.class.getName():"+ Hello.class.getName());
hello.hello();
}
}
日志输出结果:
2017-11-21 16:54:48.153 [main] INFO com.fizzbook.log4j2.Hello - Hello.class.getName():com.fizzbook.log4j2.Hello
2017-11-21 16:54:48.157 [main] TRACE com.fizzbook.log4j2.Hello - Enter
2017-11-21 16:54:48.157 [main] ERROR com.fizzbook.log4j2.Hello - Did it again!
2017-11-21 16:54:48.157 [main] INFO com.fizzbook.log4j2.Hello - 我是info信息
2017-11-21 16:54:48.157 [main] DEBUG com.fizzbook.log4j2.Hello - 我是debug信息
2017-11-21 16:54:48.157 [main] WARN com.fizzbook.log4j2.Hello - 我是warn信息
2017-11-21 16:54:48.157 [main] FATAL com.fizzbook.log4j2.Hello - 我是fatal信息
2017-11-21 16:54:48.158 [main] DEBUG com.fizzbook.log4j2.Hello - 我是debug信息
2017-11-21 16:54:48.158 [main] TRACE com.fizzbook.log4j2.Hello - Exit
该类的全限定名是com.fizzbook.log4j2.Hello,那么获取的Logger就是com.fizzbook.log4j2.Hello将继承Logger,输出trace级别及以上的日志,也就是将各级别的日志结果全部输出
我新创建一个包并重命名进行测试
此时将不是继承com.fizzbook.log4j2,因为使用getClass.getName获取的Logger名称跟包名相关,并没有与之相关的父节点,所以默认继承root Logger,root Logger级别比较高,只会输出error级别及以上的日志
复制一份Hello.java代码放入新建的包中:
结果如下:
2017-11-21 17:01:20.620 [main] ERROR com.fizzbook.log4j2_02.Hello - 当前logger的名称 :com.fizzbook.log4j2_02.Hello
2017-11-21 17:01:20.623 [main] ERROR com.fizzbook.log4j2_02.Hello - Did it again!
2017-11-21 17:01:20.623 [main] FATAL com.fizzbook.log4j2_02.Hello - 我是fatal信息
只输出了error和fatal级别的,跟我们定义的root Logger的日志级别一样。证明了推论