日志是一个非常重要的功能,任何一个应用,都离不开日志。默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台。在运行应用程序和其他例子时,你应该已经看到很多INFO级别的日志了。
从上图可以看到,日志输出内容元素具体如下:
- 时间日期:精确到毫秒
- 日志级别:ERROR, WARN, INFO, DEBUG or TRACE
- 进程ID
- 分隔符:— 标识实际日志的开始
- 线程名:方括号括起来(可能会截断控制台输出)
- Logger名:通常使用源代码的类名
- 日志内容
也许,你会在pom.xml文件中会添加依赖,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
但是,实际开发中我们**不需要**直接添加该依赖。
你会发现spring-boot-starter其中包含了 spring-boot-starter-logging,该依赖内容就是 Spring Boot 默认的日志框架 logback。
TRACE < DEBUG < INFO < WARN < ERROR < FATAL
如果设置为 WARN ,则低于 WARN 的信息都不会输出。
Spring Boot中默认配置ERROR、WARN和INFO级别的日志输出到控制台。
您还可以通过启动您的应用程序 –debug 标志来启用“调试”模式(开发的时候推荐开启),如下:
java -jar xxx.jar --debug
在application.properties中配置debug=true,该属性置为true的时候,核心Logger(包含嵌入式容器、hibernate、spring)会输出更多内容,但是你自己应用的日志并不会输出为DEBUG级别。
# 设置日志级别为 DEBUG 级别
debug=true
默认情况下,Spring Boot将日志输出到控制台,不会写到日志文件。
SpringBoot的项目,可以在application.properties或application.yml配置,这样只能配置简单的场景,保存路径、日志格式等,复杂的场景(区分 info 和 error 的日志、每天产生一个日志文件等)满足不了,只能通过自定义配置来实现。
根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载,如下:
(1)Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
(2)Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
(3)Log4j2:log4j2-spring.xml, log4j2.xml
(4)JDK (Java Util Logging):logging.properties
配置文件名字为logback-spring.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="/test/log" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<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>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/askapi.%d{yyyyMMdd}.%i.log</FileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>10MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>7</MaxHistory>
</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>
</encoder>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
private static final Logger logger = LoggerFactory.getLogger(this.getClass());
logger.info("service is start.");
如果项目中引入了lombok插件,则可以使用@Slf4j注解代替引入变量,这样就可以直接输出日志了。如下代码:
package com.shenmazong.demonew.controller;
import com.shenmazong.demonew.config.ShenmaConfig;
import com.shenmazong.demonew.config.SiteConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class IndexController {
@Autowired
SiteConfig siteConfig;
@Autowired
ShenmaConfig shenmaConfig;
@GetMapping(value = "/")
public Object index() {
log.info(siteConfig.toString());
return siteConfig;
}
@GetMapping(value = "/site")
public Object site() {
log.info(shenmaConfig.toString());
return shenmaConfig;
}
}
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/house.${PID}.%d{yyyyMMdd}.%i.log</FileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>1</MaxHistory>
</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>
</encoder>
</appender>