日志的作用不必多说,直接开始。
Springboot的spring-boot-starter-web依赖中已经默认帮我们集成了日志实现
现在的日志框架分为两类,一类是日志具体实现的框架,比如logback、log4j、log4j2等,还有一类是日志门面框架,可以认为是定义了一些统一的接口,比如slf4j、common logging
我们只需要在resources目录下新建一个对应的名字的日志配置文件,pringboot自动帮我们加载进去,如果我们没有配置,那么也是可以使用的,因为基于Springboot约定大于配置的理念,已经提供给我们了一套默认的配置。这里我们集成Logback,以Logback为例,对应依赖目录下已有一个默认配置文件base.xml。
可以看到默认的是INFO级别的日志,所以默认我们是看不到DEBUG级别的日志的。
配置文件名
那么我们这里新增一个配置文件logback-spring.xml。其实还可以使用其他文件名,日志配置也可以被加载到,拿logback来说比如logback.xml、logback.groovy、logback-spring.groovy都是可以的,但是Springboot官方推荐使用带有-spring.xml
后缀的,因为带-spring后缀的配置文件可以使用SpringBoot提供的一些高级功能,如profile多环境日志输出。这里文件名是规则固定的,如果想要自定义的话,在application.yaml
中增加配置logging.config
即可。
配置文件详解
因为logback的依赖包也都帮我们直接集成在了spring-boot-web-starter中了,所以对于开发者来说重点关注的就是日志的配置了。
可以有2种配置形式,第一种是将配置都放在application.yaml
中,另一种就是都放在我们项目目录的resources
目录下的xml配置文件中。
这里推荐使用单独的配置文件的形式,原因如下:
- 配置文件中的配置优先级其实是高于在项目application中的。
- 日志的配置比较多,而且项目如果大,也会存在很多配置,分开可以显得不臃肿。
- 单独xml配置文件的形式也比较可读,也可以比application支持更全面的配置。
- 如果无需复杂的日志配置,只需要简单使用,那么是可以在
application.yaml
文件中配置最简单的。
下面给出一个配置文件示例,里面会对所有的配置项做解释。
<?xml version="1.0" encoding="UTF-8"?>
<!--scan代表如果此配置文件发生改变,将会被重新加载,默认为true-->
<!--scanPeriod代表监测配置文件是否发生改变的时间间隔,scan为true才生效,默认1分钟-->
<!--debug代表是否打印出logback内部日志信息,默认false-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!--property标签设置变量-->
<!--设置存储路径变量-->
<property name="LOG_HOME" value="./log"/>
<!--appender是负责真正写日志的组件,每一个appender就是一个写日志的方式-->
<!--控制台输出appender-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!--设置输出格式-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%blue(%d{yyyy-MM-dd HH:mm:ss.SSS}) %yellow([%thread]) %green(%-5level) %red(%logger{50}) - %highlight(%msg%n)</pattern>
<!--设置编码-->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--文件输出,时间窗口滚动-->
<appender name="timeFileOutput" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志名,指定最新的文件名,其他文件名使用FileNamePattern -->
<File>${LOG_HOME}/timeFile/out.log</File>
<!--文件滚动模式-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名,可设置文件类型为gz,开启文件压缩-->
<FileNamePattern>${LOG_HOME}/timeFile/info.%d{yyyy-MM-dd}.%i.log.gz</FileNamePattern>
<!--日志文件保留天数,当新的日志文件被创建时,最旧的日志文件,如果是30天前的会被删除或者归档,取决于具体配置-->
<MaxHistory>30</MaxHistory>
<!--按大小分割同一天的-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!--输出格式-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!--设置编码-->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 异步输出 -->
<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="timeFileOutput"/>
</appender>
<!--指定基础的日志输出级别-->
<root level="INFO">
<!--appender将会添加到这个logger-->
<appender-ref ref="console"/>
<appender-ref ref="timeFileOutput"/>
</root>
<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
<!--logger可以对单独某些类做配置,additivity为false表示不继承root的appender,而是使用自己配置的appender-->
<logger name="com.wakaka.summer" level="DEBUG" additivity="false">
<appender-ref ref="console"/>
</logger>
</springProfile>
<!-- 生产环境. -->
<springProfile name="prod">
<logger name="com.wakaka.summer" level="INFO" additivity="false">
<appender-ref ref="timeFileOutput"/>
</logger>
</springProfile>
</configuration>
启动项目看控制台输出带颜色的日志
在项目目录下有输出的日志文件
项目中使用
如果项目没有lombok依赖,那么需要代码声明logger
@RestController
@RequestMapping("/userTest")
public class UserTestController {
private static final Logger logger = LoggerFactory.getLogger(UserTestController.class);
@Autowired
private IUserTestService iUserTestService;
@GetMapping("/addUserTest")
public boolean addUserTest(UserTest userTest) {
return iUserTestService.save(userTest);
}
@GetMapping("/updateUserTest")
public boolean updateUserTest(UserTest userTest) {
return iUserTestService.saveOrUpdate(userTest);
}
@GetMapping("/getUserTestList")
public List<UserTest> getUserTestList() {
logger.info("打印日志啦!!!!");
return iUserTestService.list();
}
}
请求接口,看到控制台打印
这里的LogFactory就是日志门面框架Slf4j提供的,方便我们后续更换日志实现框架。
如果项目中有Lombok的依赖,那么我们可以不用每个类都定义一个logger了,我们使用Slf4j
注解即可向类中注入。
@Slf4j
@RestController
@RequestMapping("/userTest")
public class UserTestController {
@Autowired
private IUserTestService iUserTestService;
@GetMapping("/addUserTest")
public boolean addUserTest(UserTest userTest) {
return iUserTestService.save(userTest);
}
@GetMapping("/updateUserTest")
public boolean updateUserTest(UserTest userTest) {
return iUserTestService.saveOrUpdate(userTest);
}
@GetMapping("/getUserTestList")
public List<UserTest> getUserTestList() {
log.info("打印日志啦");
return iUserTestService.list();
}
}