logback中logger详解 Published on 2019-01-09

 

图一

看到了没有,并没有任何的输出。

分析

​ 自己看到上面输出的结果也是很懵逼的,仔细查看了logback.xml中的代码,logger中的name指定的是自己测试代码的包啊,日志级别是info。怎么就啥都没输出啊。appender中的配置也没错啊。当初自己是找了好久的错误都没有找出来。

测试代码

​ 首先查看自己写的测试代码,自己对 private final Logger logger = LoggerFactory.getLogger("测试");这行代码产生了怀疑,这个logger形参指定的是哪一个日志框架中的对象。于是自己修改上面的测试代码如下

public class LoggerTest {     public void loggerTest() {         Logger logger = LoggerFactory.getLogger("测试");         logger.info("info=====>");         logger.error("error====》");         logger.debug("debug=====》");     } }

对logger logger = LoggerFactory.getLogger("测试"); 这行代码进行debug。进入了,如图二

图二

​ getLogger方法是slf4j中获取logger工厂,查看getILoggerFactory()方法,发现其实他就是获取一个具体的loggerFactory工厂,看过抽象工厂设计模式的应该就知道了。这里由于我们是新建了logback.xml,那么返回的工厂类其实就是logback-classic中的LoggerContext。然后调用getLogger方法创建一个Logger对象。发现返回的Logger对象如下 图三

图三

此时我们继续跟进logger.info。找到最关键的代码,如图四

图四

 

​ 该关键代码在logback-classic中的Logger类中,根据这个callAppenders方法名可以知道这就是打印日志的关键方法,继续跟进,查看callAppenders方法。如图五

图五

这个划重点了,仔细看,这个for循环中,可以看出来257行就是打印这个日志的代码了。但是这个Logger l = this; 这个代码是关键。这个this就是对象就是我们根据LoggerFactory.getLogger("测试")获取到的。继续跟进appendLoopOnAppenders方法。如图六

图六

发现是aai来打印这行日志,那么aii是怎么打印这行日志的呢,这个就要回到一开始logback.xml配置的地方了,自己配置了测试代码下的日志输出格式,但是没有配置一个logger.name 叫做”测试“的包下面的日志输出格式啊。于是自己修改logback.xml中的代码如下

<?xml version="1.0" encoding="utf-8" ?> <configuration debug="true" scan="true" scanPeriod="60 seconds">     <appender name="logger_stdout" class="ch.qos.logback.core.ConsoleAppender">         <encoder class="ch.qos.logback.classic.encoder.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 = LoggerFactory.getLogger(this.getClass()); 然后logback.xml中的logger属性中name都是指定某一包名。其实这里自己跟代码跟了挺久了其中在图五中那个for循环就是一直向上查找,logback.xml是否设置了有该包下的日志输出格式。如果查找到有该输出格式就输出,并查看logback.xml中logger中你是否设置了additivity。不是这就是默认true,继续向上查找是否还有不同的输出格式。如果设置为false,就结束。

我举一个例子吧这样就很好理解了

logback.xml代码如下

<?xml version="1.0" encoding="utf-8" ?> <!-- debug=是否打印logback内部日志 scan=是否重新加载  scanPeriod=多久扫描一次 --> <configuration debug="true" scan="true" scanPeriod="60 seconds">     <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">         <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">             <Pattern>%d{YYYY年MM月dd日 HH:mm:ss} | %-5level | %thread | %logger - %msg%n</Pattern>         </encoder>     </appender>      
                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信