Logback快速上手指南
一、环境准备
- Spring Boot2.x,SpringBoot默认采用的日志就是slf4j+logback,所以无需额外引入日志的依赖;
- IDEA集成开发环境;
- Lombok的maven依赖;
- IDEA中安装Lombok的插件;
- 从start.spring.io上新建一个demo工程,仅引入Web组件即可;
二、LogBack快速上手
2.1 最简单的使用
新建一个Rest类:
@RestController
public class DemoRest {
private static final Logger log = LoggerFactory.getLogger(DemoRest.class);
@RequestMapping("/hello")
public String sayHello(){
log.info("info level...");
return "success";
}
}
由于我们使用了lombok,所以可以简写成:
@Slf4j
@RestController
public class DemoRest {
@RequestMapping("/hello")
public String sayHello(){
log.info("info level...");
return "success";
}
}
@slf4j注解的作用,就是替代类中的private static final Logger log = LoggerFactory.getLogger(DemoRest.class);
,如此logback就能正常输出日志了。
2.2 使用配置文件
在真实的项目开发中,对于日志输出的路径、策略和格式都是有不同要求的,这些就可以在配置文件中进行设置。
Spring Boot默认会检测src/main/resources
下面的logback-spring.xml
作为logback的配置文件。
现在我们设置配置文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%t] [%C] [%L] [%-5p] %m%n</pattern>
</layout>
</appender>
<root level="info">
<appender-ref ref="CONSOLE-LOG" />
</root>
</configuration>
这里有两个元素要介绍下:
- appender表示一个日志输出组件,我们可以同时配置多个日志输出组件,以满足不同的需求。当然,此处我们配置一个即可,当前只要能实现在控制台打印日志。其中,name是自己起的,表示这是一个用于定义控制台输出日志组件,layout表示输出日志的格式。(有关日志格式的配置参考第三节的推荐资料)
- root定义了日志的输出级别,在这里,level为info表示只有等级大于等于info的日志才会被输出。root中的appeder-ref是用来引入日志组件,使得这些组件生效。如果我们定义了appender组件,却没有在root中包含,那这些appender组件就不会启用。
2.3 日志输出到文件
除了要将日志输出到控制台,我们更希望将它们输出到固定目录的文件中保存,这才是标准应用的通用做法。那么我们只需要在上面的基础上增加一个appender日志组件即可。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--定义全局变量-->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %msg%n"/>
<!--输出到控制台-->
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${LOG_PATTERN}</pattern>
</layout>
</appender>
<!--输出到文件-->
<appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>C://Users//xxx//Desktop//info//%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="CONSOLE-LOG" />
<appender-ref ref="FILE-LOG" />
</root>
</configuration>
新的日志组件我们取名字叫FILE-LOG
,encoder
和pattern
也是用来定义日志输出格式的,因为格式和上面已经定义的输出到控制台的日志格式相同,我们将它们提取出来,放到配置文件的最上面property
里面,将来调整日志格式只要改这一个地方即可,其它日志组件想要使用相同的输出格式,直接引用该变量。
rollingPolicy
表示滚动策略,这里指定基于时间顺序的滚动策略,然后在fileNamePattern
中设置日志存放的路径和日志名称,maxHistory
表示最多保留天数。
最后,别忘了在root
中引入我们的文件日志输出组件,使之生效。
2.4 日志按级别分类存储到文件
在每天日志量都很多的情况下,我们想查看ERROR
级别的日志来定位问题,使用如上一个日志文件的方式,显得很费劲。此时我们可以将ERROR
级别的日志分类到一个单独的日志文件中。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--定义全局变量-->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %msg%n"/>
<property name="LOG_DIR" value="C:\\Users\\xxx\\Desktop\\info"/>
<!--输出到控制台-->
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${LOG_PATTERN}</pattern>
</layout>
</appender>
<!--输出到文件-->
<appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--设置过滤器过滤ERROR级别的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!--错误日志设置-->
<appender name="ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_DIR}/error.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE-LOG" />
<appender-ref ref="FILE-LOG" />
<appender-ref ref="ERROR-LOG" />
</root>
</configuration>
首先,我们需要重新设置FILE-LOG
日志组件,让它不再将ERROR
级别的日志记录到文件中,因为我们在下面会设置专门的日志组件来记录它。
filter
采用的是LevelFilter
,严格匹配ERROR
级别的日志,当匹配onMatch
的时候,就deny拒绝记录,当不匹配onMismatch
的时候,就access
接受记录。
当然,如果你仍然需要将ERROR级别的日志记录到该日志文件中,上述filter不用配置就行。
接下来,我们定义一个ERROR-LOG
的输出组件,专门用来收集ERROR级别的日志。ThresholdFilter
表示设定的日志级别及以上级别将会被记录。
最后,别忘了引用我们的错误日志输出组件。
2.5 日志按类名分类存储到文件
有的时候,我们需要单独监控某一个模块的日志,那么logback也支持为某一个类或者某一个包单独打印日志到另外的文件中。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--定义全局变量-->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %msg%n"/>
<property name="LOG_DIR" value="C:\\Users\\xxx\\Desktop\\info"/>
<!--输出到控制台-->
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${LOG_PATTERN}</pattern>
</layout>
</appender>
<!--输出到文件-->
<appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--设置过滤器过滤ERROR级别的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!--错误日志设置-->
<appender name="ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_DIR}/error.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到文件-->
<appender name="BB-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/bb-%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<logger name="com.xxx.yyy.bb" level="INFO" additivity="false">
<appender-ref ref="BB_FILE_LOG"/>
</logger>
<root level="info">
<appender-ref ref="CONSOLE-LOG" />
<appender-ref ref="FILE-LOG" />
<appender-ref ref="ERROR-LOG" />
</root>
</configuration>
我们在原有的配置文件基础上,加上一个logger
配置,将指定包com.xxx.yyy.bb
下的info级别及以上的日志输出都会使用BB_FILE_LOG
输出组件。而在BB_FILE_LOG
我们可以自定义输出的格式及文件。
需要额外注意additivity
这个属性,其默认值为true,表示同时会记录到该包专属的日志文件bb-%d.log
中和外层的统一日志文件%d.log
中。这个其实很好理解,该包的代码是包含在整个工程里面的,外层日志输出组件当然也有记录它的必要。然而,当设置其值为false时,外层的日志输出组件就不再对它进行记录。
2.6 异步日志输出
当系统并发量较大,日志输出较多的时候,可以考虑使用异步日志输出的方案。
由于2.5节的配置文件已经内容较多了,我们使用2.2节的配置说剑做出说明。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--定义全局变量-->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %msg%n"/>
<!--输出到控制台-->
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${LOG_PATTERN}</pattern>
</layout>
</appender>
<!--输出到文件-->
<appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>C://Users//xxx//Desktop//info//%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!--异步文件日志设置-->
<appender name="ASYNC-FILE-LOG" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE-LOG"/>
</appender>
<root level="info">
<appender-ref ref="CONSOLE-LOG" />
<appender-ref ref="ASYNC-FILE-LOG" />
</root>
</configuration>
我们需要增加一个异步日志输出组件,在这个组件中引用原来同步输出日志组件,然后设置以下参数信息即可。
首先,discardingThreshold
设置为0表示不丢弃任何日志。因为,默认情况下,当队列容量只剩下20%的时候,会自动丢弃WARN
级别以下的日志,而我们是想要记录INFO
级别的,不允许丢弃任何日志,所以设置为0。
其次,queueSize
表示容纳日志事件的队列,默认情况下就是256,当队列已满的情况下,新的日志事件将会全部丢弃,直到日志队列被消费后不再已满,才能接受新的日志事件。
这两个参数都是可以自己调整设置的,看系统需求。