前言
上一篇主要对root进行了实践总结,现在基于上一篇中的springboot代码环境对logback.xml中的logger来进行实践和自己遇到的坑。
logger简介
日志属性,可以根据logger中的name属性指定某个文件或者文件夹输出的日志级别,并通过appender-ref指定日志的输出格式。还有一个additivity属性,如果设置为false的话就不会向上传递。
上代码
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="com.example.logback.logger" level="info">
<!-- 指定输出的appender -->
<appender-ref ref="logger_stdout"/>
</logger>
</configuration>
测试代码:
package com.example.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 = LoggerFactory.getLogger("测试");
public void loggerTest() {
logger.info("info=====>");
logger.error("error====》");
logger.debug("debug=====》");
}
}
单元测试代码:
package com.example.logback;
import com.example.logback.logger.LoggerTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
@SpringBootTest
public class LogbackApplicationTests {
@Resource
private LoggerTest loggerTest;
@Test
public void loggerTest(){
loggerTest.loggerTest();
}
}
输出结果如下,图一
图一
看到了没有,并没有任何的输出。
分析
自己看到上面输出的结果也是很懵逼的,仔细查看了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>
<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 在该aa.bb.cc 下的日志输出格式 这个就是在aa.bb.cc.dd 上的日志输出格式-->
<logger name="aa.bb.cc" level="info">
<!-- 指定输出的appender -->
<appender-ref ref="logger_stdout"/>
</logger>
<!-- 指定name 在该aa.bb.cc.dd 下的日志输出格式 additivity 默认为true 可以向上传递-->
<logger name="aa.bb.cc.dd" level="info" >
<appender-ref ref="stdout"/>
</logger>
</configuration>
测试代码如下
package com.example.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 = LoggerFactory.getLogger("aa.bb.cc.dd.ee");
public void loggerTest() {
logger.info("info=====>");
logger.error("error====》");
logger.debug("debug=====》");
}
}
单元测试代码如 上代码里面的单元测试代码一样。
得到结果如下:
图八
总结
LoggerFactory.getLogger(name),其中name对应着logback.xml中logger属性中name=对应的子包,当然你也可以设置一样的。logger中的additivity设置为false是代表该logger日志打印不向上传递, appender-ref指定的日志输出格式。
下一篇把logback.xml中的appender属性介绍一下并进行实践。
logback中logger详解的更多相关文章
-
logback 常用配置详解<;appender>;
logback 常用配置详解 <appender> <appender>: <appender>是<configuration>的子节点,是负责写日志的 ...
-
logback 常用配置详解(二) <;appender>;
logback 常用配置详解(二) <appender> <appender>: <appender>是<configuration>的子节点,是负责写 ...
-
logback使用配置详解
title: logback使用配置详解 date: 2017-04-25 16:42:49 tags: 日志 --- 1.介绍 Logback是由log4j创始人设计的另一个开源日志组件,它当前分为 ...
-
logback常用配置详解及logback简介
logback 简介(一) Ceki Gülcü在Java日志领域世界知名.他创造了Log4J ,这个最早的Java日志框架即便在JRE内置日志功能的竞争下仍然非常流行.随后他又着手实现SLF4J 这 ...
-
org.apache.log4j.Logger详解
org.apache.log4j.Logger 详解 1. 概述 1.1. 背景 在应用程序中添加日志记录总的来说基于三个目的 :监视代码中变量的变化情况,周期性的记录到文件*其他应用进行统计分析工 ...
-
【转】logback 常用配置详解(序)logback 简介
原创文章,转载请指明出处:http://aub.iteye.com/blog/1101222, 尊重他人即尊重自己 详细整理了logback常用配置, 不是官网手册的翻译版,而是使用总结,旨在更快更透 ...
-
lombok+slf4j+logback SLF4J和Logback日志框架详解
maven 包依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lomb ...
-
org.apache.log4j.Logger 详解
org.apache.log4j.Logger 详解 1. 概述 1.1. 背景 在应用程序中添加日志记录总的来说基于三个目的 :监视代码中变量的变化情况,周期性的记录到文件*其他应用进行统计 ...
-
SLF4J和Logback日志框架详解
SLF4J和Logback日志框架详解 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 本文讲述SLF4J和Logback日志框架. SLF4J是一套 ...
随机推荐
-
lightbox使用
使用方法: 1.在页面头部包含 lightbox.js 文件并加载 lightbox.css 样式表文件 <script type="text/javascript" src ...
-
Filter实现用户名验证
①:使用Filter,判断用户名是否为空,为空的话返回登录画面. 1,web.xml: 1.<filter> 2. <filter-name>SecurityServlet&l ...
-
centos下搭建lamp环境
1 在线安装所有的服务 yum -y install httpd mysql mysql-server php php-mysql postgresql postgresql-server php-p ...
-
linux man使用方法 和centos安装中文man包 --转
http://blog.chinaunix.net/uid-25100840-id-302308.html 这两天学习<linux设备驱动程序开发详解>中的异步通知,其中有一个fcntl( ...
-
深入浅出C++引用(Reference)类型
要点1:为反复使用的.冗长的变量名称定义一个简短的.易用的别名,从而简化了代码.通常,冗长的变量名称源于多层嵌套对象,例如类中定义嵌套类,类中定义其它类对象. //------ 未使用引用的程序片段, ...
-
NET Core 以及与 .NET Framework
简析.NET Core 以及与 .NET Framework的关系 简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core ...
-
iOS app 发布错误 ERROR ITMS-90167: ";No .app bundles found in the package";
今天iOS 上传 APP 突然发生了这个错误,在排查非证书错误后感到非常奇怪, 因为昨天刚刚上传了另一个APP,一切正常. 仔细回忆了下 昨天和今天唯一的不同就是我升级了 电脑操作系统至 macOS ...
-
36.中国特色*的*中有这样的现象:地方省*要坚持党的领导和按 照国务院的指示进行安全生产。请编写一个java应用程序描述上述的*现象。 要求如下: (1)该应用程序中有一个“党*”接口:CentralPartyCommittee,该接口中 有个“坚持党的领导”方法:void partyLeader() (2)该应用程序中有一个“国务院”抽象类:StateCouncil,该抽象类中有
//接口:CentralPartyCommittee package jieKou; public interface CentralPartyCommittee { void partyLeader ...
-
<;Dare To Dream>; 第四次作业:基于原型的团队项目需求调研与分析
任务1:实施团队项目软件用户调研活动. (1)真实的用户调研对象:生科院大三学生 (2)利用实验七所开发的软件原型:网站原型链接 (3)要有除原型法之外的其他需求获取手段: 访谈法 开会研讨法 (4) ...
-
zzw_rsync命令中的/的作用
[root@sv0379 rsync]# rsync -vzrtopg --password-file=/usr/local/rsync/rsync.passwd /opt/aspire/prod ...