Spring Boot日志全攻略|手把手教你玩转日志框架


目录

1.前言

2.日志使用

2.1 打印日志

2.1.1 在程序中得到日志对象

2.1.2 使用日志对象打印日志

2.2 日志框架介绍(了解)

2.2.1 门面模式(外观模式)

2.2.2 SLF4]框架介绍

2.3 日志格式的说明

2.4 日志级别

2.4.1 日志级别的分类

2.4.2 日志级别的使用

2.5 日志配置

2.5.1 配置日志级别

2.5.2 日志持久化

2.5.3 配置日志文件分制

2.5.4 配置日志格式

3.更简单的日志输出

3.1 添加 lombok 依赖

3.2 输出日志

4.总结


1.前言

哈喽大家好啊,今天来给大家分享的是Spring开发中日志的使用。日志在软件开发中扮演着至关重要的角色,它就像是系统运行的 “黑匣子”,记录着程序执行过程中的各种信息,帮助我们定位问题、分析系统状态,对于 Spring 开发而言,掌握日志的使用更是开发过程中的必备技能,下面我将详细为大家讲解 Spring 日志的相关内容。

2.日志使用

这里给大家提供一个日志在一个应用场景的使用:

2.1 打印日志

这是启动Spring程序时就有的日志:

2.1.1 在程序中得到日志对象

在 Spring 中,要想使用日志功能,首先得获取日志对象。一般我们会借助日志框架提供的工厂类来获取。例如,使用commons-logging框架时,可以通过LogFactory来获取日志对象:

Log log = LogFactory.getLog(YourClass.class);
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OrderService {
    // 通过类名初始化日志对象
    private static final Logger logger = 
            LoggerFactory.getLogger(OrderService.class);
}

这种方式也是比较常见的,LoggerFactory作为日志工厂,能够根据配置为我们创建相应的日志记录器,与具体的日志实现框架相配合,实现日志功能。

2.1.2 使用日志对象打印日志

为了方便调试,我们这里编写了这样一段程序:

package springlog.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/log")
@RestController
public class LogController {
    private static Logger logger = LoggerFactory.getLogger(LogController.class);

    @RequestMapping("/print")
    public String print(){
        System.out.println("sout打印日志");
        logger.info("logger打印日志");
//        logger.trace("trace");
//        logger.debug("debug");
//        logger.warn("warn");
//        logger.debug("debug");
//        logger.error("error");
        return "打印日志";
    }
}

运行起来程序,访问本地的8080端口号下的/log/print :

再回去看日志:

可以看到日志已被打出。

2.2 日志框架介绍(了解)

2.2.1 门面模式(外观模式)

门面模式(Facade Pattern)是一种 结构型设计模式,主要用于简化复杂系统的调用方式。这里用一部分代码来解释门面模式:

核心思想:

  • 提供一个统一的高层接口,隐藏子系统的复杂性,使客户端只需与门面交互,而无需直接调用多个底层组件。

  • 类比现实:就像电灯的 总开关,按一次就能控制所有灯(无需逐个操作卧室、客厅、走廊的灯)。


核心代码:

package springlog.facade;

public interface Light {
    void on();
    void off();
}
package springlog.facade;

public class FacadeClient{
    private  LivingRoomLight livingRoomLight = new LivingRoomLight();
    private BedroomLight bedroomLight = new BedroomLight();
    private HallLight hallLight = new HallLight();

    public void on() {
        livingRoomLight.on();;
        bedroomLight.on();
        hallLight.on();
    }

    public void off() {
        livingRoomLight.off();
        bedroomLight.off();
        hallLight.off();
    }

}
package springlog.facade;

public class Main {

    public static void main(String[] args) {
        FacadeClient facadeClient = new FacadeClient();
        facadeClient.on();
        facadeClient.off();
    }
}

日志源码 · 爱吃烤鸡翅的酸菜鱼/springboot学习 - 码云 - 开源中国 https://gitee.com/crjs-hao/springboot/tree/master/src/main/java/springlog代码中角色划分:

角色对应代码作用
子系统(Subsystem)BedroomLightLivingRoomLightHallLight实际执行业务的底层组件(如具体的灯)
门面(Facade)FacadeClient聚合子系统功能,提供简化的接口(如on()/off()一键操作所有灯)
客户端(Client)Main 类只依赖门面,不直接操作子系统

关键设计要点:

(1) 简化接口

  • 门面类 FacadeClient 将多个灯的开关操作封装成两个方法:

    public void on() {
        livingRoomLight.on();
        bedroomLight.on();
        hallLight.on();
    }

    客户端只需调用 facadeClient.on(),无需关心具体哪些灯被打开。

(2) 解耦客户端与子系统

  • 客户端(Main)仅依赖 FacadeClient,不直接操作 Light 的实现类。

  • 如果未来灯的类需要修改(例如替换为智能灯泡),只需调整 FacadeClient,客户端代码无需变动。

(3) 符合迪米特法则(最少知识原则)

  • 客户端不需要知道子系统内部的复杂关系(如灯的依赖、初始化顺序等),只需通过门面交互。


门面模式的优点:

优点在本例中的体现
降低复杂度客户端无需分别操作三个灯,只需调用门面的 on()/off()
提高可维护性修改子系统(如增加新灯)时,只需调整门面类,不影响客户端
减少耦合客户端代码不依赖具体灯的实现类,仅依赖门面
易于扩展新增子系统组件(如厨房灯)时,只需在门面中整合,无需修改现有客户端逻辑

门面模式通过 封装复杂细节提供简洁接口,实现了客户端与子系统的解耦。在需要统一管理多个关联组件时(如智能家居控制、多层系统调用),它能显著提升代码的可维护性和易用性。

2.2.2 SLF4]框架介绍

SLF4J(Simple Logging Facade for Java) 是 Java 的一个 日志门面框架(日志抽象层),它本身不提供日志实现,而是提供统一的 API,允许开发者自由选择底层日志框架(如 Logback、Log4j2、JUL 等)。

特性说明
门面模式(Facade)提供统一的日志接口,不依赖具体实现(类似 JDBC 驱动与数据库的关系)
兼容多种日志实现支持 Logback、Log4j2、Java Util Logging(JUL)等作为底层实现
占位符({})功能使用 logger.info("User: {}, Age: {}", name, age) 避免字符串拼接,提高性能

优势有哪些:

✅ 解耦:代码只依赖 SLF4J API,更换日志实现无需修改业务代码。
✅ 性能优化{} 占位符比字符串拼接更高效(避免无效的 String 操作)。
✅ 灵活性:可自由切换日志实现,适应不同环境(如测试用 Logback,生产用 Log4j2)。
✅ 兼容性:解决 Java 生态中多种日志框架并存的问题(如 Hibernate 用 JBoss Logging,Spring 用 Commons Logging)。 

2.3 日志格式的说明

2023-08-20 14:22:45.678  INFO 25484 --- [  main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http)

 各字段含义:

  1. 日期时间:精确到毫秒

  2. 日志级别:此处为INFO

  3. 进程ID

  4. 线程名([main]表示主线程)

  5. Logger名称(通常为类名)

  6. 日志消息

时间 + 日志级别 + 进程ID + 应用名称 + 线程名称 + 类的路径 + 日志内容

2.4 日志级别

2.4.1 日志级别的分类

日志的级别从高到低依次为:FATAL、ERROR、WARN、INFO、DEBUG、TRACE

  1. - FATAL:致命信息,表示需要立即被处理的系统级错误。
  2. - ERROR:错误信息,级别较高的错误日志信息,但仍然不影响系统的继续运行。
  3. - WARN:警告信息,不影响使用,但需要注意的问题。
  4. - INFO:普通信息,用于记录应用程序正常运行时的一些信息,例如系统启动完成、请求处理完成等。
  5. - DEBUG:调试信息,需要调试时候的关键信息打印。
  6. - TRACE:追踪信息,比DEBUG更细粒度的信息事件(除非有特殊用意,否则请使用DEBUG级别替代)

2.4.2 日志级别的使用

测试代码:

package springlog.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/log")
@RestController
public class LogController {
    private static Logger logger = LoggerFactory.getLogger(LogController.class);

    @RequestMapping("/print")
    public String print(){
        System.out.println("sout打印日志");
        logger.info("logger打印日志");
        logger.trace("trace");
        logger.debug("debug");
        logger.warn("warn");
        logger.debug("debug");
        logger.error("error");
        return "打印日志";
    }
}

在实际开发中,我们需要根据不同的场景合理选择日志级别。在开发阶段,可以适当使用debug和trace级别来获取详细的调试信息,帮助我们快速定位问题。而在生产环境中,为了减少日志对系统性能的影响,通常会将日志级别设置为info或warn及以上。例如,对于一些关键业务逻辑的正常执行情况使用info级别记录,对于可能出现的潜在问题使用warn级别提醒,而对于程序中的错误则使用error级别进行详细记录。同时,我们还可以通过配置文件动态地调整日志级别,以便在不同的运行阶段灵活地控制日志的输出量和详细程度。

2.5 日志配置

2.5.1 配置日志级别

在yml配置文件中设置日志类型:

logging:
  level:
    root: info
    main:
      java:
        springlog:
          controller: trace

我们可以看到,切换后日志就与之前不一样了。

2.5.2 日志持久化

为什么要做日志持久化?

三大关键要点

  1. 故障追溯:保留完整的系统运行记录

  2. 性能分析:通过历史日志分析系统瓶颈

  3. 安全审计:满足等保合规要求

配置yml文件,启动项目后刷新:

logging:
#  level:
#    root: info
#    main:
#      java:
#        springlog:
#          controller: trace
  file:
    name: log/log.log

可以看到日志被放在包中的一个文件中。

如果采用相对路径配置:

file:
    path: logger/

logging.file,path 设置日志的路径。

logging.file.name 设置日志的名称,可以带绝对路径或者相对路径。
如果两个配置,同时存在,以 logging.file.name为主(即优先级高)

 properties配置格式:

 

# 指定完整日志路径(优先使用)
logging.file.name=/var/log/myapp/application.log

# 或指定目录(生成spring.log)
logging.file.path=/var/log/myapp

2.5.3 配置日志文件分制

如果我们把日志都放在一个文件中,随着项目的运行,日志文件会越来越大,所以需要对日志文件进行分割。

logging:
  logback:
    rollingpolicy:
      # 单个日志文件最大体积(支持KB/MB/GB单位)
      max-file-size: 100MB
      # 保留历史日志天数(滚动删除)
      max-history: 30
      # 总日志容量上限
      total-size-cap: 10GB
      # 文件名模式(时间+序号)
      file-name-pattern: "${LOG_FILE}.%d{yyyy-MM-dd}.%i.log"
参数说明生产环境推荐值
max-file-size触发分割的单个文件大小100-500MB
max-history保留旧日志文件天数15-60天
total-size-cap日志文件总量限制磁盘空间的70%
file-name-pattern滚动文件命名规则必须包含%d(日期)和%i(序号)

2.5.4 配置日志格式

logging:
  pattern:
    # 控制台格式(带ANSI颜色)
    console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){cyan} %clr(%-5level){magenta} %clr(%logger{35}){blue} - %msg%n"
    
    # 文件格式(结构化)
    file: "%d{ISO8601}|%thread|%-5level|%logger{35}|%msg%n"

格式符号速查表

占位符说明示例
%d日期时间%d{yyyy-MM-dd HH:mm:ss}
%thread线程名main
%-5level左对齐日志级别INFO
%logger{length}类名缩写c.e.s.UserService
%msg日志消息User login success
%n换行符 
%X{key}MDC上下文值%X{traceId}
%clr()ANSI颜色块%clr(INFO){blue}

3.更简单的日志输出

在开发过程中,为了简化日志输出代码,提高开发效率,我们可以借助 Lombok 提供的日志注解功能。通过添加 Lombok 依赖并使用相应的注解,能够自动生成日志记录器代码,从而减少模板化代码的编写。

3.1 添加 lombok 依赖

在maven中添加Lombok依赖:

<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.30</version>
			<scope>provided</scope>
		</dependency>

3.2 输出日志

引入 Lombok 依赖后,可以通过在类上添加特定的注解来自动生成日志记录器对象。最常用的就是这个:

@Slf4j

功能就相当于:

private static Logger logger = LoggerFactory.getLogger(LogController.class);

测试代码: 

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class LogController {
 public void log(){
 log.info("--------------要输出⽇志的内容----------------");
 }
}

4.总结

今天的分享到这里就结束了,喜欢的小伙伴点点赞点点关注,需要所有的源代码可以去我的gitee上就可以啦~你的支持就是对我最大的鼓励,大家加油!

另外最后的最后,欢迎大家加入我的社区哦,初创社区难免经验不足,请大家多多包涵,也欢迎大家前来多多交流。

爱吃烤鸡翅的酸菜鱼社区-CSDN社区云 https://bbs.csdn.net/forums/aaa1f71356f6475db42ea9ea09a392bc?spm=1001.2014.3001.6682

 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃烤鸡翅的酸菜鱼

希望大家对我多多支持喔~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值