目录
一、日志文件的作用
二、自定义打印日志
2.1 SpringBoot 中的日志框架
2.1.1 SLF4J
2.2 为什么需要实现自定义日志打印?
2.3 实现自定义打印
2.3.1 获取日志对象
三、日志级别
3.1 日志级别的作用
3.2 日志级别的分类和使用
3.2.1 日志的级别分为;
3.2.2. 日志的级别设置
四、日志的持久化
4.1 设置日志的保存路径
4.2 设置日志的保存名称
4.3 日志的存储大小
4.4 生产界别日志分类
五、使用Lombok实现更简单的日志输出
5.1 添加Lombok依赖
5.2 输出日志
5.3 Lombok更多注解使用
5.4 Lombok原理解释
六 、总结
日志是程序的重要组成部分,想象一下,如果程序报错,而没有相对应的日志来查看,那么你可以快速的找到问题所在吗?
答案是否定的,因此日志对于我们来说,最主要的用途就是排除和定位问题。
除了常见的发现和定位问题之外,我们还可以通过日志实现下面这些功能:
以上都是日志提供的非常实现的功能。
我们知道,在Spring Boot项目启动的时候默认就会有日志的输出,如下图所示:
可以得知,SpringBoot其实是内置了日志框架(SLF4J+logback):
SLF4J(Simple Logging Facade for Java)是Java编程语言的日志门面(Logging Facade)框架,它提供了一种简单且统一的方式来管理和使用不同日志系统的日志功能。
简单来说,可以理解为像JDBC一样(JDBC是Java的一个API,用于连接和操作数据库),程序是通过SLF4J来选择具体使用哪种不同的日志系统,而不需要关注日志系统本身。
当程序需要更换日志的时候,那么就只需要通过SLF4J修改一下就好了,并不需要全局修改。
佐证:
在任意一个的SpringBoot项目中都可以找到:
很多人可能会问,直接使用System.out.println 打印不就好了,为什么还需要学会自定义日志呢?
这是因为在参加开发的过程中,产品是需要在很多环境下运行的,比如在开发环境和生产环境中,我们需要看到的日志是完全不一样的,开发环境中需要看到调试信息,报警信息,错误信息等等,而生产环境中我们是不需要调试信息的,如果调试信息放到生产环境中,这是会造成数据污染的,会让开发者无法快速的定位到错误信息。
其次,System.out.println是无法实现持久化的,对后续定位和排查问题造成很大的影响。
开发者实现自定义日志打印步骤如下:
需要明确,日志是类级别的,因为每个方法都有可能需要日志的打印,设立在方法中就不太合理。
private static final Logger log = LoggerFactory.getLogger(TestController.class);
分析:因为每个日志信息需要打印出自己所对应的类,所以是private修饰,又因为希望在类中直接使用,又不希望被修改,因此使用static 和 final修饰
注意:
Logger 对象是属于 org.slf4j 包下的,不要导⼊错包。
实现代码如下:
package com.example.demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
//@Controller
//@ResponseBody
// @RestController可替代以上两个注解
@RestController
public class TestController {
// 1. 得到日志框架
private static final Logger log = LoggerFactory.getLogger(TestController.class);
@RequestMapping("/sayhi")
public String sayHi() {
// System.out.println("打印日志");
log.trace("i'm trace");
log.debug("i'm debug");
log.info("i'm info");
log.warn("i'm warn");
log.error("i'm error");
return "hello world";
}
}
localhost:8080/sayhi访问该地址后:
在获取日志对象的时候其实还可以使用如下这种方式,但是这种方式由于只打印出类名,而不是包名+类名,定位的精确度不高,不被广泛使用:
日志级别的设置需要在SpringBoot项目中的配置文件中设置,其中.yml配置文件中的语法如下:
logging:
level:
root: error
使用启动类运行代码后,控制台打印如下:
当然,以上这种设置方法是针对全局设置的,也可以根据实际情况针对某个包下的某个类来控制日志的打印级别:
分析:这里先对全局日志的打印级别做出设置, 然后再对com->example->demo->controller包下的类进行级别的控制,由于该包的设置的级别为trace,所以日志将打印与trace级别相等和比trace级别高的日志。
因为生产环境的需要,日志是需要保存下来的,以便后续追溯问题,把日志保存下来的过程就叫做日志的持久化。
实现日志持久化可由以下任一步骤完成:
设置保存路径的语法如下:
# 开发环境配置文件
server:
port: 7777
# 日志保存路径(1.尽量将日志文件选择存储到系统盘,2.路径不要出现中文和空格)
logging:
file:
path: D:\\Log_test
代码展示如下:
分析:观察发现日志是相同的,说明在yml中设置了日志保存路径的方法是正确的,该方法设置后会在保存路径下生成一个spring.log文件(默认情况下文件名就为这个)。
设置名称的语法如下:
# 开发环境配置文件
server:
port: 7777
# 日志保存路径(1.尽量将日志文件选择存储到系统盘,2.路径不要出现中文和空格)
logging:
file:
name: springboot.log
# path: D:\\Log_test
由于没有设置目录只设置了名称,所以生成的日志文件就存储到当前项目的同一目录下;
当然,也可以设置目录,这样就可以在指定目录下存储可以自己命名的日志:
注意,日志的内容最好不要为中文,否则可能会出现编码不一致而导致乱码的问题。
在yml配置文件中通过以下代码进行设置:
logging:
file:
max-size: 10MB
当程序的运行日志超过10MB的时候,程序会自行再创建一个日志文件进行保存日志。
根据业务场景划分,日志主要是分为两种:
由于每次使用LoggerFactory.getLogger(xxx.class) 很繁琐且每个类都添加⼀遍,也很麻烦,这⾥讲⼀种更好⽤的⽇志输出⽅式,使⽤ lombok 来更简单的输出:
org.projectlombok
lombok
1.18.20
true
访问地址后,控制台能够正常打印:
基本注解
注解 | 作用 |
@Getter | 自动添加 getter 法 |
@Setter | 自动添加 setter 法 |
@ToString | 自动添加 toString 法 |
@EqualsAndHashCode | 自动添加 equals 和 hashCode 法 |
@NoArgsConstructor | 自动添加参构造法 |
@AllArgsConstructor | 自动添加全属性构造法,顺序按照属性的定义顺序 |
@NonNull | 属性不能为 null |
@RequiredArgsConstructor | 自动添加必需属性的构造法,final + @NonNull 的 属性为必需 |
组合注解
组合注解 | 作用 |
@Data | @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor |
日志注解
注解 | 作用 |
@Slf4j | 添加一个名为 log 的日志,使slf4j |
我们知道正常的Java程序运行原理如下;
而Lombok则是在编译期间进行干预:Lombok的注解会自己对应上下文的语义,然后生成对应的字节码文件。
也正是因为如此,使用Lombok并不会拖慢程序的运行效率。
在tagger文件夹下找到对应的testcontroller的字节码文件,打开其所在文件路径,将文件拖到idea中:
观察发现 ,其实就当前日志注解而言,其实底层Lombok对应着其实是Logger:
⽇志是程序中的重要组成部分,使用日志可以快速的发现和定位问题,Spring Boot 内容了日志框架,默认情况下使用的是 info 日志级别将日志输出到控制台的,我们可以通过 lombok 提供的 @Slf4j 注解和 log 对象快速的打印⾃定义日志,日志包含 6 个级别:
日志级别依次提升,而日志界别越⾼,收到的日志信息也就越少,我们可以通过配置日志的保存名称或保存目录来将日志永久地保存下来