logback中logger详解
前⾔
上⼀篇主要对root进⾏了实践总结,现在基于上⼀篇中的springboot代码环境对l中的logger来进⾏实践和⾃⼰遇到的坑。
logger简介
⽇志属性,可以根据logger中的name属性指定某个⽂件或者⽂件夹输出的⽇志级别,并通过appender-ref指定⽇志的输出格式。还有⼀个additivity属性,如果设置为false的话就不会向上传递。
上代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<appender name="logger_stdout" class="ch.ConsoleAppender">
<encoder class="ch.qos.der.PatternLayoutEncoder">
<Pattern>%d{YYYY-MM-dd HH:mm:ss} | %-5level | %thread | %logger - %msg%n</Pattern>
</encoder>
</appender>
<!-- name=指定打印⽇志⽂件级别 level=⽇志级别 additivity=是否想向上传递先不加上 additivity=false 属性 -->
<logger name="ample.logback.logger" level="info">
<!-- 指定输出的appender -->
<appender-ref ref="logger_stdout"/>
</logger>
</configuration>
测试代码:
ample.logback.logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @ClassName LoggerTest
* @Description TODO
* @Author ouyangkang
* @Date 2019-01-07 17:04
**/
@Component
public class LoggerTest {
private final Logger logger = Logger("测试");
public void loggerTest() {
logger.info("info=====>");
<("error====》");
logger.debug("debug=====》");
}
}
单元测试代码:
ample.logback;
ample.logback.logger.LoggerTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.st.context.SpringBootTest;
import st.context.junit4.SpringRunner;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
springboot其实就是spring@SpringBootTest
public class LogbackApplicationTests {
@Resource
private LoggerTest loggerTest;
@Test
public void loggerTest(){
loggerTest.loggerTest();
}
}
输出结果如下,图⼀
图⼀
看到了没有,并没有任何的输出。
分析
⾃⼰看到上⾯输出的结果也是很懵逼的,仔细查看了l中的代码,logger中的name指定的是⾃⼰测试代码的包啊,⽇志级别是info。怎么就啥都没输出啊。appender中的配置也没错啊。当初⾃⼰是了好久的错误都没有出来。
测试代码
⾸先查看⾃⼰写的测试代码,⾃⼰对 private final Logger logger = Logger("测试");这⾏代码产⽣了怀疑,这个logger形参指定的是哪⼀个⽇志框架中的对象。于是⾃⼰修改上⾯的测试代码如下
public class LoggerTest {
public class LoggerTest {
public void loggerTest() {
Logger logger = Logger("测试");
logger.info("info=====>");
<("error====》");
logger.debug("debug=====》");
}
}
对logger logger = Logger("测试"); 这⾏代码进⾏debug。进⼊了,如图⼆
图⼆
getLogger⽅法是slf4j中获取logger⼯⼚,查看getILoggerFactory()⽅法,发现其实他就是获取⼀个具体的loggerFactory⼯⼚,看过抽象⼯⼚设计模式的应该就知道了。这⾥由于我们是新建了l,那么返回的⼯⼚类其实就是logback-classic中的LoggerContext。然后调⽤getLogger⽅法创建⼀个Logger对象。发现返回的Logger对象如下图三
图三
此时我们继续跟进logger.info。到最关键的代码,如图四
图四
该关键代码在logback-classic中的Logger类中,根据这个callAppenders⽅法名可以知道这就是打印⽇志的关键⽅法,继续跟进,查看callAppenders⽅法。如图五
图五
这个划重点了,仔细看,这个for循环中,可以看出来257⾏就是打印这个⽇志的代码了。但是这个Logger l = this; 这个代码是关键。这个this就是对象就是我们根据Logger("测试")获取到的。继续跟进appendLoopOnAppenders⽅法。如图六
图六
发现是aai来打印这⾏⽇志,那么aii是怎么打印这⾏⽇志的呢,这个就要回到⼀开始l配置的地⽅了,⾃⼰配置了测试代码下的⽇志输出格式,但是没有配置⼀个logger.name 叫做”测试“的包下⾯的⽇志输出格式啊。于是⾃⼰修改l中的代码如下
<?xml version="1.0" encoding="utf-8" ?>
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<appender name="logger_stdout" class="ch.ConsoleAppender">
<encoder class="ch.qos.der.PatternLayoutEncoder">
<Pattern>%d{YYYY-MM-dd HH:mm:ss} | %-5level | %thread | %logger - %msg%n</Pattern>
</encoder>
</appender>
<!-- name=指定打印⽇志⽂件级别 level=⽇志级别 additivity=是否想向上传递先不加上 additivity=false 属性 -->
<logger name="测试" level="info">
<!-- 指定输出的appender -->
<appender-ref ref="logger_stdout"/>
</logger>
</configuration>
运⾏单元测试,得出结果如下图七
图七
有了⽇志输出。
思考
我看公司代码⼀般获取⽇志对象都是 private final Logger logger = Class()); 然后l中的logger属性中name都是指定某⼀包名。其实这⾥⾃⼰跟代码跟了挺久了其中在图五中那个for循环就是⼀直向上查,l是否设置了有该包下的⽇志输出格式。如果查到有该输出格式就输出,并查看l中logger中你是否设置了additivity。不是这就是默认true,继续向上查是否还有不同的输出格式。如果设置为false,就结束。
我举⼀个例⼦吧这样就很好理解了
<?xml version="1.0" encoding="utf-8" ?>
<!-- debug=是否打印logback内部⽇志 scan=是否重新加载 scanPeriod=多久扫描⼀次 -->
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<appender name="stdout" class="ch.ConsoleAppender">
<encoder class="ch.qos.der.PatternLayoutEncoder">
<Pattern>%d{YYYY年MM⽉dd⽇ HH:mm:ss} | %-5level | %thread | %logger - %msg%n</Pattern>
</encoder>
</appender>
<appender name="logger_stdout" class="ch.ConsoleAppender">
<encoder class="ch.qos.der.PatternLayoutEncoder">
<Pattern>%d{YYYY-MM-dd HH:mm:ss} | %-5level | %thread | %logger - %msg%n</Pattern>
</encoder>
</appender>
<!-- 指定name 在该 下的⽇志输出格式这个就是在dd 上的⽇志输出格式-->
<logger name="" level="info">
<!-- 指定输出的appender -->
<appender-ref ref="logger_stdout"/>
</logger>
<!-- 指定name 在该dd 下的⽇志输出格式 additivity 默认为true 可以向上传递-->
<logger name="dd" level="info" >
<appender-ref ref="stdout"/>
</logger>
</configuration>
测试代码如下
ample.logback.logger;
ample.logback.logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @ClassName LoggerTest
* @Description TODO
* @Author ouyangkang
* @Date 2019-01-07 17:04
**/
@Component
public class LoggerTest {
private final Logger logger = Logger("dd.ee");
public void loggerTest() {
logger.info("info=====>");
<("error====》");
logger.debug("debug=====》");
}
}
单元测试代码如上代码⾥⾯的单元测试代码⼀样。
得到结果如下:
图⼋
总结
下⼀篇把l中的appender属性介绍⼀下并进⾏实践。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论