LogBack日志
1、简介
SpringBoot对所有内部日志使用通用日志记录,但保留底层日志实现。为Java Util Logging、Log4J2和Logback提供了默认配置。在不同的情况下,日志记录器都预先配置为使用控制台输出,同时还提供可选的文件输出。
默认情况下,SpringBoot使用Logback进行日志记录。
SpringBoot中默认使用Logback进行日志输出,可以同时使用通过logback的配置文件logback-spring.xml或是SpringBoot框架的配置文件application.yml进行配置。
1.1、logback日志组件
Logback是一款开源日志组件,属于Log4j的升级版本,现在项目组使用的次数越来越多。
Logback主要有下面的特性:
(1)更快的执行速度:基于我们先前在Log4j上的工作,Logback 重写了内部的实现,在某些特定的场景上面,甚至可以比之前的速度快上10倍。在保证Logback的组件更加快速的同时,同时所需的内存更加少;
(2)充分的测试:Logback 历经了几年,数不清小时数的测试。尽管Log4j也是测试过的,但是Logback的测试更加充分,跟Log4j不在同一个级别。我们认为,这正是人们选择Logback而不是Log4j的最重要的原因。谁不希望即使在恶劣的条件下,你的日志框架依然稳定而可靠呢?
(3)由三个模块组成
logback-core
logback-classic
logback-access
logback-core是其它模块的基础设施,其它模块基于它构建,显然,logback-core提供了一些关键的通用机制。
logback-classic的地位和作用等同于 Log4J,它也被认为是 Log4J的一个改进版,并且它实现了简单日志门面 SLF4J;
而 logback-access主要作为一个与 Servlet容器交互的模块,比如说tomcat或者 jetty,提供一些与 HTTP访问相关的功能。
1.2、日志级别
日志等级有(从高到低):fatal、error、warn、info、debug、trace、off
fatal(致命) error(错误) warn(警告) info (信息) debug(调试) trace(跟踪) off(关闭)
1.3、打印日志方式
1.3.1、使用Class方式
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
@RestController
public class UserController {
private final Logger log = LoggerFactory.getLogger(UserController.class);
@GetMapping("/getLogback")
public void getLogback() {
log.info("info级别日志");
log.debug("debug级别日志");
log.warn("warn级别日志");
log.error("error级别日志");
}
}
1.3.2、使用注解@Slf4j
/**
* @author mengyibei
* @version 1.0
* @description: TODO
* @date 2023/5/9 11:17
*/
@Slf4j
@RestController
public class UserController {
@GetMapping("/getLogback")
public void getLogback() {
log.info("info级别日志");
log.debug("debug级别日志");
log.warn("warn级别日志");
log.error("error级别日志");
}
}
2、logback-spring.xml配置详情
2.1、SpringBoot配置文件加载顺序
logback.xml --> application.properties --> logback-spring.xml
2.2、日志级别
日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出
2.3、logback-spring.xml 的配置项
共有一个父标签、两种属性、三个节点:
一个父标签:configuration
两种属性:contextName和property
三个节点:appender、root、logger
2.3.1、父标签configuration
scan
当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true
scanPeriod
设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug
当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
<configuration scan="true" scanPeriod="10 seconds"></configuration>
2.3.1、两种属性contextName 和 property
2.3.1.1、 contextName
每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
如果同时存在logback.xml和logback-spring.xml,或者同时存在logback.xml和自定义的配置文件,则会先加载logback.xml,再根据application配置加载指定配置文件,或加载logback-spring,xml。如果这两个配置文件的contextName不同,就会报错
# logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
</configuration>
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback_demo</contextName>
</configuration>
2.3.1.2、 property
用来定义变量值的标签, 有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
例如使用定义上下文名称,然后在设置logger上下文时使用。
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="LOGBACK_NAME" value="myLogback" />
<contextName>${LOGBACK_NAME}</contextName>
</configuration>
2.3.2、三个节点 appender、root、logger
2.3.2.1、 appender节点
appender的意思是追加器,在这里可以理解为一个日志的渲染器(或者说格式化日志输出)。比如渲染console日志为某种格式,渲染文件日志为另一种格式。
appender中有name和class两个属性,有rollingPolicy和encoder两个子节点。
name表示该渲染器的名字,class表示使用的输出策略,常见的有控制台输出策略和文件输出策略。
控制台输出
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
encoder表示输出格式:
%d表示时间
%thread表示线程名
%-5level 表示日志级别,允许以五个字符长度输出
%logger{50}表示具体的日志输出者,比如类名,括号内表示长度
%msg表示具体的日志消息,就是logger.info(“xxx”)中的xxx
%n表示换行
文件输出
文件输出主要包括配置:以指定格式将日志输出到指定文件夹下的文件中,可以配置该文件的名称、最大大小、保存时间等。
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<!--先将今天的日志保存在这个文件中-->
<file>${log.path}/log_debug.log</file>
<!--日志文件输出格式 %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
%d{HH: mm:ss.SSS}——日志输出时间
%thread——输出日志的进程名字,这在Web应用以及异步任务处理中很有用
%-5level——日志级别,并且使用5个字符靠左对齐
%logger{36}——日志输出者的名字
%msg——日志消息
%n——平台的换行符
-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<!--如果第二天输出日志,会将当天的日志记录在<file>${log.path}/log_debug.log</file>,然后将昨天的日志归档到下面的文件中-->
<!--以分钟切分 %d{yyyy-MM-dd_HH-mm}-->
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<!--单个日志文件最大100M,到了这个值,就会再创建一个日志文件,日志文件的名字最后+1-->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大20G,超过就会删除旧的日志-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--
此日志文件只记录debug级别的
onMatch和onMismatch都有三个属性值,分别为Accept、DENY和NEUTRAL
onMatch="ACCEPT" 表示匹配该级别及以上
onMatch="DENY" 表示不匹配该级别及以上
onMatch="NEUTRAL" 表示该级别及以上的,由下一个filter处理,如果当前是最后一个,则表 示匹配该级别及以上
onMismatch="ACCEPT" 表示匹配该级别以下
onMismatch="NEUTRAL" 表示该级别及以下的,由下一个filter处理,如果当前是最后一个,则不匹配该级别以下的
onMismatch="DENY" 表示不匹配该级别以下的
-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
2.3.2.2、 root
root节点实际上是配置启用哪种appender,可以添加多个appender
<!--root配置必须在appender下边-->
<!--root节点是对所有appender的管理,添加哪个appender就会打印哪个appender的日志-->
<!--root节点的level是总的日志级别控制,如果appender的日志级别设定比root的高,会按照appender的日志级别打印日志,-->
<!--如果appender的日志级别比root的低,会按照root设定的日志级别进行打印日志-->
<!--也就是说root设定的日志级别是最低限制,如果root设定级别为最高ERROR,那么所有appender只能打印最高级别的日志-->
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
2.3.2.3、logger 对单个包或类添加配置:
<!--
name:用来指定受此loger约束的某一个包或者具体的某一个类。
addtivity:是否向上级loger传递打印信息。默认是true。
-->
<!-- logback为 com.demo.mengyb 中的包 -->
<logger name="com.demo.mengyb" level="debug" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<!-- logback为 com.demo.mengyb.DemoemoApplicationTests 这个类 -->
<logger name="com.demo.mengyb.DemoemoApplicationTests" level="INFO" additivity="true">
<appender-ref ref="STDOUT"/>
</logger>
2.3.2.4、logger和root的关系
root和logger是父子的关系: logger的appender根据参数additivity决定是否要叠加root的appender,logger的级别是其自身定义的级别,和root的级别没什么关系。
logger对单个包或类添加配置,相当于局部配置,root相当于全局配置: 如果logger里面配置了additivity=“false”,就会覆盖root的,只打印一遍;但是additivity=“true”,就会向上层再次传递,不会覆盖,而是打印两遍!
2.4、环境配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<!--配置多环境日志输出 可以在application.properties中配置选择哪个profiles : spring.profiles.active=dev-->
<!--生产环境:输出到文件-->
<springProfile name="pro">
<root level="info">
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
<appender-ref ref="WARN_FILE" />
</root>
</springProfile>
<!--开发环境:打印控制台-->
<springProfile name="dev">
<root level="debug">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
</configuration>