SpringBoot日志全解析:从调试到持久化

一. 日志的用途

  • 排错调试:出问题时看日志,快速定位代码哪里错、参数是什么、异常栈在哪。
  • 监控运行状态:看程序启动是否成功、接口是否正常、服务有没有卡顿。
  • 记录关键行为:谁登录了、调用了什么接口、操作了什么数据,方便追溯。
  • 统计与分析:接口耗时、访问量、错误率,用于优化性能和容量规划。
  • 线上问题复盘:服务崩溃、宕机后,靠日志还原现场。

简单一句话:

日志就是 Spring Boot 项目的"黑匣子",用来记录、排查、监控、追溯一切运行信息。

二. 日志使用

Spring Boot 项目在启动的时候默认就有日志输出,如下图所示:

它打印的⽇志和 System.out.print 有什么不同呢

System.out.prin 打的日志:

使用日志对象打印对象:

java 复制代码
@RestController
public class LoggerController {
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/logger")
    public String logger(){
        logger.info("打印⽇志");
        return "打印⽇志成功";
    }
}

可以看到,我们通过 System.out.print 打印的日志,比 SpringBoot 打印的日志缺少了很多信息.

SpringBoot内置了日志框架Slf4j ,我们可以直接在程序中调⽤Slf4j 来输出⽇志

2.1 打印日志

打印日志的步骤:

  • 在程序中得到日志对象.
  • 使用日志对象输出要打印的内容.

在程序中得到日志对象:

在程序中获取日志对象需要使用日志工厂 LoggerFactory,如下代码所示:

java 复制代码
private static Logger logger = LoggerFactory.getLogger(LoggerController.class);//一般为固定代码

我们通常用 LoggerFactory.getLogger(当前类.class) 来获取日志对象,这个方法会根据传入的类信息,生成一个与当前类绑定的日志对象。

不同类获取的日志对象,会在输出日志时带上自己类的名称,方便你快速定位日志来源。(每个类都可以获取属于自己的独立日志对象)

注意:Logger 对象是属于 org.slf4j 包下的, 不要导⼊错包.

使用日志对象输出要打印的内容:

⽇志对象的打印⽅法有很多种,我们可以先使⽤info()⽅法来输出⽇志,如下代码所⽰:

java 复制代码
package logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class LoggerController {
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/logger")
    public String logger(){
        logger.info("打印⽇志");
        return "打印⽇志成功";

    }

}

2.2 日志格式的说明

当我们在配置文件中加入以下配置会发生什么:

python 复制代码
spring.application.name=logger

我们发现日志多出来个内容--- 项目名称

注意:该配置是我们在创建Spring Boot项目时自动生成的 properties 配置文件中所自带的配置项

2.3 日志级别

⽇志级别代表着⽇志信息对应问题的严重性,为了更快的筛选符合⽬标的⽇志信息.

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

• FATAL:致命信息,表⽰需要⽴即被处理的系统级错误.

• ERROR:错误信息,级别较⾼的错误⽇志信息,但仍然不影响系统的继续运⾏.

• WARN:警告信息,不影响使⽤,但需要注意的问题

• INFO:普通信息,⽤于记录应⽤程序正常运⾏时的⼀些信息,例如系统启动完成、请求处理完成等.

• DEBUG:调试信息,需要调试时候的关键信息打印. (Spring默认不打印)

• TRACE:追踪信息,⽐DEBUG更细粒度的信息事件(除⾮有特殊⽤意,否则请使⽤DEBUG级别替代)(默认不打印)

日志级别的顺序:

针对这些级别, Logger 对象分别提供了对应的⽅法,来输出⽇志.,代码如下所示:

python 复制代码
@RestController
public class LoggerController {
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/logger")
    public String logger(){
        logger.trace("================= trace ===============");
        logger.debug("================= debug ===============");
        logger.info("================= info ===============");
        logger.warn("================= warn ===============");
        logger.error("================= error ===============");
   
        return "打印⽇志成功";

    }

}

我们发现 debug 和 trace 级别的日志没有被打印---这与⽇志级别的配置有关,⽇志的输出级别默认是 info级别(下面的内容中会讲到如何配置), 所以只会打印⼤于等于此级别的⽇志,也就 是 info , warn 和 error.

2.4 日志配置

2.4 1 配置日志级别

日志级别配置只需要在配置文件中设置"logging.level"配置项即可,如下所示:

java 复制代码
logging:
  level:
    root: trace
 

加上这个配置后,所有trace级别的日志后,与它同级及高于此级的日志都可以打印出来了

注意:我们这里设置的日志级别是默认针对整个文件的,我们还可以指定文件进行日志级别的配置,配置代码如下所示:

python 复制代码
logging:
  level:
    root: debug
    logger: info #logger为当前项目下的一个包名

2.4.2 日志持久化

以上的⽇志都是输出在控制台上的, 重启服务器日志就会丢失,然而在线上环境中, 我们需要把⽇志保存下来, 以便出现问题之后追 溯问题. 把⽇志保存下来就叫持久化.

日志持久化有两种方式:

  • 配置日志的存储目录:
java 复制代码
logging:
  file:
   path: logger/

我们刷新后就可以发现在logger这个目录下出现了 Spring.log (日志文件的默认名称)这个日志文件 (注意: logging.file.path: 只能设置日志文件的路径,不能设置文件名称)

即使我们重启服务器,日志信息也不会消失

  • 配置日志路径+名称:
java 复制代码
logging:
  file:
    name: logger/loggerInformation

注意: logging.file.name:不仅能设置日志文件的路径,还能设置文件名称

注意: logging.file.name 和 logging.file.path 两个都配置的情况下, 只生效其⼀ ,以 logging.file.name 为准.

2.4.3 配置日志文件分割

如果我们的⽇志都放在⼀个⽂件中,随着项⽬的运⾏,⽇志⽂件会越来越⼤,需要对⽇志⽂件进⾏分割.

java 复制代码
logging:
  file:
    name: logger/loggerInformation
  logback:
    rollingpolicy:
      max-file-size: 1KB
      file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i

注意:必须配合 logging.file.name 使用: ${LOG_FILE} 变量需要依赖 name 配置才能正确解析。

  1. 日志文件超过1KB就分割(设置1KB是为了更好展示.企业开发通常设置为200M,500M等,此处没 有明确标准)

  2. 分割后的日志文件名为:日志名.日期.索引

2.2.4 配置日志格式

⽬前⽇志打印的格式是默认的

打印⽇志的格式, 也是⽀持配置的. ⽀持控制台和⽇志⽂件分别设置

配置说明:

  1. 颜色渲染 %clr(表达式){颜色}
  • 作用:设置输出日志的颜色,提升控制台可读性。

  • 支持颜色: blue 、 cyan 、 faint 、 green 、 magenta 、 red 、 yellow

  • 示例: %clr(%5p){yellow} (将日志级别显示为黄色)

  1. 日期和时间 %d{...}
  • 作用:输出日志产生的日期和时间,可精确到毫秒。

  • 完整格式:

plaintext

%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}

  • 说明:

  • 先尝试读取系统属性 LOG_DATEFORMAT_PATTERN 。

  • 若该属性不存在,则使用默认格式 yyyy-MM-dd'T'HH:mm:ss.SSSXXX (ISO8601 标准格式)。

  • 可通过 System.getProperty("LOG_DATEFORMAT_PATTERN") 获取系统属性。

  1. 日志级别 %5p
  • %p :显示日志级别( ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE )。

  • %5p :将级别名称右对齐,固定占 5 个字符宽度,不足则用空格填充(如 INFO )。

  • %-5p :将级别名称左对齐,固定占 5 个字符宽度,不足则用空格填充(如 INFO )。

  1. 上下文信息占位符
  • %t / %thread :线程名称

  • %c :类的全限定名

  • %M :方法名

  • %L :行号

  • %m / %msg :日志输出消息

  • %n :平台无关的换行符

  1. 宽度与截断控制
  • %5 :字符长度小于 5 时,右边用空格填充(右对齐)

  • %-5 :字符长度小于 5 时,左边用空格填充(左对齐)

  • %.15 :字符长度超过 15 时,截去多余字符

  • %15.15 :字符长度小于 15 时右边填充,超过 15 时截断,固定 15 字符宽度

java 复制代码
logging:
  file:
    name: logger/loggerInformation
  logback:
    rollingpolicy:
      max-file-size: 1KB
      file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
  pattern:
    console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr([%15.15t]){magenta} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n"
    file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"

如果设置了颜色,却没有生效? --- 需要配置,让idea⽀持控制台颜色显式。操作如下:

在输入框中输入 -Dspring.output.ansi.enabled=ALWAYS ,再点击 OK 并重启即可

三. 更简单的日志打印

每次都使⽤ LoggerFactory.getLogger(xxx.class) 很繁琐, 且每个类都添加⼀遍, lombok给我们提供了 ⼀种更简单的方式.

lombok提供的 @Slf4j 会帮我们提供⼀个日志对象log,我们直接使用就可以.

步骤:

  • 引入lombok依赖
java 复制代码
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <optional>true</optional>
</dependency>
  • 使用 @slf4j 注解输出日志
java 复制代码
@RestController
@Slf4j
public class LoggerController {

    @RequestMapping("/logger")
    public String logger(){
        log.trace("================= trace ===============");
        log.debug("================= debug ===============");
        log.info("================= info ===============");
        log.warn("================= warn ===============");
        log.error("================= error ===============");

        return "打印⽇志成功";

    }

}
相关推荐
zopple1 小时前
Knife4j文档请求异常(基于SpringBoot3,查找原因并解决)
java·服务器·数据库
小鸡吃米…2 小时前
Python线程同步
开发语言·数据结构·python
老友@2 小时前
接口调用的演进史——从“发 HTTP 请求”到“可治理的系统能力
spring boot·后端·架构
清水白石0082 小时前
Python 弱引用深度解析——让缓存不再成为内存泄漏的温床
java·python·缓存
zzb15802 小时前
RAG from Scratch-优化-routing
java·前端·网络·人工智能·后端·python·mybatis
白帽子黑客-宝哥2 小时前
渗透测试“保姆级”实战成长手册
开发语言·网络安全·渗透测试·php
脑子不好真君2 小时前
手势操控的粒子土星 (Three.js + MediaPipe)
开发语言·javascript·ecmascript
深蓝轨迹2 小时前
IDEA 中 Spring Boot 配置文件的自动提示消失(无法扫描配置文件)的完整解决方案
java·spring boot·intellij-idea
杀神lwz2 小时前
Java Json压缩工具类
java·json