一:SpringBoot日志概述
(1)日志作用
SpringBoot日志作用:Spring Boot提供了强大的日志支持,它使用了一种灵活的方式来集成和配置各种日志框架
- 统一日志抽象层: Spring Boot通过
spring-boot-starter-logging
依赖提供了对Commons Logging
、Logback
、Log4j2
和java.util.logging
等常见日志框架的支持。这意味着你可以选择喜欢的日志框架,Spring Boot会为你提供一个统一的日志抽象层 - 简化配置: Spring Boot通过默认配置,减少了对日志框架的繁琐配置。默认情况下,它使用
Logback
作为默认的日志框架,而且提供了默认的日志配置文件,你可以在需要的时候自定义 - 动态日志级别: Spring Boot支持动态修改日志级别,这意味着你可以在应用运行时调整日志级别,而无需重新启动应用。这对于诊断和排查问题非常有帮助
- 丰富的输出格式: Spring Boot支持多种日志输出格式,包括控制台输出、文件输出、JSON格式输出等。你可以根据应用需求选择适合的输出格式
- 集成了Spring的特性: Spring Boot的日志集成了Spring框架的特性,比如使用
@Slf4j
注解为类生成Logger对象,方便在代码中使用日志 - 日志文件滚动: 针对文件输出,Spring Boot支持日志文件的滚动,可以配置按大小、按时间等方式生成新的日志文件,防止单个日志文件过大
具体到程序开发上,日志对我们有如下作用
- 记录⽤户登录⽇志,⽅便分析⽤户是正常登录还是恶意破解⽤户
- 记录系统的操作⽇志,⽅便数据恢复和定位操作⼈
- 记录程序的执⾏时间,⽅便为以后优化程序提供数据⽀持
(2)如何使用日志
SpringBoot项目在启动时默认会输出日志
这些信息的含义如下
- ①:日志打印时间
- ②:日志打印级别
- ③:线程ID
- ④:线程名称
- ⑤:执行的类名
- ⑥:日志信息
二:自定义日志打印
自定义日志打印:需要两步
- 第一步:利用
LoggerFactory.getLogger(Object.class)
获取日志对象。LoggerFactory
需要将每个类传递进去,这样才能知道日志的归属类,继而才能定位到问题 - 第二步:使用日志对象相应方法打印日志信息,这里暂时先用
info()
方法
如下
package com.example.springbootfirst2023_11_12;
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;
@Controller
@ResponseBody
@RequestMapping("/log")
public class LogController {
// 得到日志对象
private static final Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/getlog")
public String sayHi() {
logger.info("我是info");
return "Hello";
}
}
三:日志级别
(1)概述
SpringBoot日志级别:Spring Boot日志级别用于控制日志信息的输出程度,它决定了哪些级别的日志信息会被记录,其目的在于筛选重要信息,Spring Boot支持常见的日志级别,主要包括以下几个
- TRACE(追踪): 最详细的日志级别,通常用于追踪程序的执行流程。TRACE级别的日志信息包含非常详细的信息,如方法的输入参数、执行过程中的关键步骤等
- DEBUG(调试): 用于输出调试信息,对于定位问题和分析程序行为非常有用。DEBUG级别的日志信息包含比TRACE略少但仍然很详细的信息
- INFO(信息): 用于输出一般信息,通常用于标识应用程序的正常运行状态。INFO级别的日志信息提供了应用程序运行时的一般状态
- WARN(警告): 表示潜在的问题,这些问题并不会导致应用程序失败,但可能需要注意。WARN级别的日志信息用于警告开发者或者运维人
- ERROR(错误): 表示错误事件,可能会导致应用程序的某些功能失效。ERROR级别的日志信息通常用于记录程序运行中的异常情况
- FATAL(致命): 这是一些非常严重的错误,通常会导致应用程序无法继续执行。FATAL级别的日志信息很少被使用,因为大多数情况下ERROR已经足够
从上到下日志级别越来越高,当程序中设置了日志级别之后,程序只会打印和设置级别相同和大于当前日志级别的日志,小于当前级别的日志不会输出
package com.example.springbootfirst2023_11_12;
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;
@Controller
@ResponseBody
@RequestMapping("/log")
public class LogController {
// 得到日志对象
private static final Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/getlog")
public String sayHi() {
logger.trace("=============trace============");
logger.debug("=============debug============");
logger.info("=============info============");
logger.warn("=============warn============");
logger.error("=============error============");
return "Hello";
}
}
(2)设置日志级别
设置日志级别:在配置文件中可以设置日志级别
如下,设置日志级别从debug开始
logging:
level:
root: debug
package com.example.springbootfirst2023_11_12;
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;
@Controller
@ResponseBody
@RequestMapping("/log")
public class LogController {
// 得到日志对象
private static final Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/getlog")
public String sayHi() {
logger.trace("=============trace============");
logger.debug("=============debug============");
logger.info("=============info============");
logger.warn("=============warn============");
logger.error("=============error============");
return "Hello";
}
}
如下,实际开发时我们可能常常只关注某个类(例如controller)的日志信息,而不需要其他额外信息,那么可以把全局日志设置为error
,然后待观察类的日志设置较低即可(针对不同文件夹设置不同日志级别)
配置方法如下
root
表示全局日志级别
logging:
level:
root: error
com:
example:
springbootfirst2023_11_12:
controller: trace
package com.example.springbootfirst2023_11_12.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;
@Controller
@ResponseBody
@RequestMapping("/log")
public class LogController {
// 得到日志对象
private static final Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/getlog")
public String sayHi() {
logger.trace("=============trace============");
logger.debug("=============debug============");
logger.info("=============info============");
logger.warn("=============warn============");
logger.error("=============error============");
return "Hello";
}
}
四:日志持久化(保存日志)
日志持久化:日志默认是输出在控制台上的,而在生产环境上我们需要保存日志,以便出现问题后进行追溯,有两种方式
- 方式一:配置日志文件的保存路径
- 方式二:配置日志文件的文件名
# 方式一
logging:
file:
path: C:\Log
# 方式二
logging:
file:
path: C:\Log\test.log
注意
- 控制台上只有日志信息会保存,像
System.out.println()
这些是无法保存的 - 日志文件是以追加方式保存的
- SpringBoot存在最大日志大小限制(可以设置
logging.logback.rollingpolicy.max-file-size
,默认为10M),当超过此限制大小后,会再创建一个日志文件记录
五:lombok
(1)使用lombok方便输出日志
可以看到每次都使用LoggerFactory.getLogger(LogController.class)
是很麻烦的,所以我们可以使用lombok方便输出
- 第一步:在想要输出日志的类上添加
@slf4j
注解 - 第二步:使用
log
对象输出日志(只能使用它)
package com.example.springbootfirst2023_11_12.controller;
import lombok.extern.slf4j.Slf4j;
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;
@Controller
@ResponseBody
@Slf4j
@RequestMapping("/log")
public class LogController {
// 得到日志对象
@RequestMapping("/getlog")
public String sayHi() {
log.trace("=============slf4j:trace============");
log.debug("=============slf4j:debug============");
log.info("=============slf4j:info============");
log.warn("=============slf4j:warn============");
log.error("=============slf4j:error============");
return "Hello";
}
}
(2)注解总结
注解 | 功能 |
---|---|
@ToString | 修饰JavaBean,可以动态生成相应的ToString方法,格式为:User(username=admin, password=123)<br / |
@EqualsAndHashCode | 修饰JavaBean,默认情况下,会使用所有非静态(non-static)和非瞬态(non-transient)属性来生成equals和hasCode |
@Getter | 可以修饰JavaBean,也可以修饰属性,生成相应属性的get()方法 |
@Setter | 可以修饰JavaBean,也可以修饰属性,生成相应属性的set()方法 |
@NonNull | 修饰方法参数,自动判断参数是否为null,为nulll则抛出NullPointerException |
@NoArgsConstructor | 修饰JavaBean,可以动态生成无参构造器方法 |
@RequiredArgsConstructor | 修饰JavaBean,生成private构造方法,使用staticName选项生成指定名称的static方法,与@NonNull联用,指定那些属性是本方法参数 |
@AllArgsConstructor | 修饰JavaBean,可以动态生成全参构造器方法 |
@Data | 修饰JavaBean,集合了@ToString、@EqualsAndHashCode、@Getter/@Setter、@RequiredArgsConstructor的所有特性。 |
@Value | 修饰JavaBean,和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法 |
@Slf4j | 修饰JavaBean,当项目中使用Slf4j日志架构的时候自动创建log日志实例 |
@Log4j | 修饰JavaBean,当项目中使用Log4j日志架构的时候自动创建log日志实例,需要创建log4j.properties配置文件,推荐使用@Log4j2 |
@Log4j2 | 修饰JavaBean,当项目中使用Log4j日志架构的时候自动创建日志实例,不需要配置文件 |
@Synchronized | 修饰方法,自动生成同步代码块锁 |
@Cleanup | 修饰流变量,自动调用close()方法 |
评论区