做前端开发可能对日志接触不多,但是日志对后端开发重要性毋庸置疑,它对于监控应用的运行状态、问题排查等都有非常重要的意义。这篇文章简单介绍一下 SpringBoot 日志的配置。
slf4j
slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback)
log4j
og4j是apache实现的一个开源日志组件。通过使用log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
logback
logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现,所以logback与slf4j的结合最好。
log4j2
Log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活。
SpringBoot 默认使用 logback 日志系统,如果不需要更改为其他日志系统,则无需多余的配置,logback 默认将日志打印到控制台上。
如果要使用 logback ,原则上需要添加 spring-boot-starter-logging
的依赖,但是在 spring-boot-starter-web
中已经包含了 spring-boot-starter-logging
,因此无需再添加依赖。
在 SpringBoot 中,日志级别从高到低分别为:
TRACE < DEBUG < INFO < WARN < ERROR < FATAL
在默认情况下,SpringBoot 使用 INFO 级别输出到控制台,在 SpringBoot 项目启动的时候,应该可以看到很多 INFO 级别的日志了:
从上图可以看到,日志输出内容都会包含以下元素:
然后有一个注意点,如果当前的级别设置为 INFO
,那么低于 INFO
级别的日志都不会输出:
从上图可以看到,低于 INFO 的都没有打印。个人认为这个功能还是比较实用的,例如在开发阶段,可以把日志的级别设为 DEBUG ,方便调试,然后到测试阶段,可以把日志级别设为 INFO ,这样就隐藏了 DEBUG 的日志,然后到部署上线的时候把日志级别设为 ERROR ,只打印错误日志,这样就可以过滤掉不重要的内容。
前面介绍了日志的概念,这里介绍如何使用日志。使用的话比较简单,在类的里面加一句代码:
private final Logger logger = LoggerFactory.getLogger(当前类名.class);
然后就可以使用了:
public class DemoLogTest {
private final Logger logger = LoggerFactory.getLogger(DemoLogTest.class);
@Test
public void test1() {
logger.trace("======测试内容======");
logger.debug("======测试内容======");
logger.info("======测试内容======");
logger.warn("======测试内容======");
logger.error("======测试内容======");
}
}
这里需要注意下,后面那个 getLogger
传的参数,是 当前类名.class
。事实上,传一个别的类名也不会报错,只不过打印出来的日志里的类,就变成了你传进去的类:
从上图可以看出,打印出来的日志的类,就是你传进去的类。因此准确编写 class 信息能够提供快速定位日志的效率。
从上面的示例代码可以看出,每次想打印日志的时候,都需要在类中加一句这样的代码:
private final Logger logger = LoggerFactory.getLogger(当前类名.class);
如果每次都写这行代码会很麻烦,可以使用 @Slf4j
注解,这个注解需要 lombok
依赖。在类的前面加上这个注解,然后使用 log
打印日志:
@Slf4j
public class DemoLogTest {
@Test
public void test1() {
log.trace("======测试内容======");
log.debug("======测试内容======");
log.info("======测试内容======");
log.warn("======测试内容======");
log.error("======测试内容======");
}
}
如果是 Controller 方法也是一样用:
@Slf4j
@RestController
@RequestMapping("user")
public class UserController {
@PostMapping("validateUser")
public ResponseEntity<ServerResponse> userValidate(@RequestBody @Validated UserDTO userDTO) {
log.info("======测试内容======");
return ServerResponse.ok(userDTO);
}
}
在本机环境,我们习惯在控制台看日志,但是线上我们还是要通过将日志信息保存到日志文件中。那么应该如何配置才能将日志信息保存到文件呢?
在我们创建的 SpringBoot 项目中,resources目录下有个application.properties文件(如果是application.yml文件也是同样的道理,只是采用的不同的编写风格而已)。添加如下配置:
logging.path=/Users/jackie/workspace/rome/
logging.file=springbootdemo.log
logging.path 用来配置日志文件的路径
logging.file 用来配置日志文件名,如果该属性不配置,默认文件名为spring.log
日志级别总共有TRACE < DEBUG < INFO < WARN < ERROR < FATAL ,且级别是逐渐提供,如果日志级别设置为INFO,则意味TRACE和DEBUG级别的日志都看不到。
在applicaition.properties中添加如下配置:
logging.level.root=warn
上面是用的root级别,即项目的所有日志,我们也可以使用package级别,即指定包下使用相应的日志级别。下面root的级别还是INFO,但是将指定包下的日志级别设置为WARN:
logging.level.root=INFO
logging.level.com.jackie.springbootdemo.config=WARN
在application.properties中添加:
logging.pattern.console=%d{
yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n
logging.pattern.file=%d{
yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
上述配置的编码中,对应符号的含义如下:
%d{HH:mm:ss.SSS}
:日志输出时间%thread
:输出日志的进程名字,这在Web应用以及异步任务处理中很有用%-5level
:日志级别,并且使用5个字符靠左对齐%logger-
:日志输出者的名字%msg
:日志消息%n
:平台的换行符Spring Boot各种日志记录方式详解
Spring Boot 日志配置(超详细)
Spring Boot系列——日志配置