首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Spring Boot 日志

Spring Boot 日志

作者头像
趙卋傑
发布2026-01-12 16:01:58
发布2026-01-12 16:01:58
820
举报

1.日志概述

JavaSE部分我们使用System.out.print来打印日志,通过打印日志来发现和定位问题,或者根据日志来分析程序的运行过程,在Spring的学习中,也经常根据控制台的日志来分析和定位问题

比如需要记录一些用户的操作记录(一些审计公司会要求),也可能需要使用日志来记录用户的一些喜好,把日志持久化,后续进行数据分析等.但是System.out.print不能很好的满足我们的需求,我们就需要使用一些专门日志框架(专业的事情交给专业的人去做)

1.1 日志的用途

  1. 系统监控
  2. 数据采集
  3. 日志审计

2.日志使用

2.1 打印日志

打印日志的步骤:

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

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

代码语言:javascript
复制
private static Logger logger = LoggerFactory.getLogger(LoggerController.class);

LoggerFactory·getLogger需要传递一个参数,标识这个日志的名称.这样可以更清晰的知道是哪个类 输出的日志,当有问题时,可以更方便直观的定位到问题类

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

2.1.2 使用日志对象打印日志

验证码日志对比

代码语言:javascript
复制
System.out.println("System生成的日志:" + code);
logger.info("logger生成的日志" + code);

2.2 日志框架

SLF4J不同于其他日志框架,它不是一个真正的日志实现,而是一个抽象层,对日志框架制定的一种规范,

标准,接口.所有SLF4J并不能独立使用,需要和具体的日志框架配合使用,

2.2.1 门面模式(外观模式)

SLF4J是门面模式的典型应用(但不仅仅使用了门面模式)

门面模式定义

门面模式(FacadePattern)又称为外观模式,提供了一个统一的接口,用来访问子系统中的一群接口.

其主要特征是定义了一个高层接口,让子系统更容易使用.

原文: Provide a unified interface to a set of interfaces in a subsystem.Facade defines a higher- level interface that makes the subsystem easier to use. 解释:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行,门面模式提供一个高层 次的接口,使得子系统更易于使用。

门面模式主要包含2种角色:

外观角色(Facade):也称门面角色,系统对外的统一接口.

子系统角色(SubSystem):可以同时有一个或多个SubSystem.每个SubSytem都不是一个单独的类,而是一个类的集合.SubSystem并不知道 Facade 的存在,对于 SubSystem而言,Facade 只是另一个客户端而已(即 Facade 对 SubSystem透明)

比如去医院看病,可能要去挂号,门诊,化验,取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便.

门面模式的实现

场景:回家,我们会开各个屋的灯.离开家时,会关闭各个屋的灯

如果家里设置一个总开关,来控制整个屋的灯就会很方便

我们使用门面模式的实现

代码语言:javascript
复制
/**
 * 灯的⻔⾯ 
 */
class LightFacade{
    private Light livingRoomLight = new LivingRoomLight();
    private Light hallLight = new HallLight();
    private Light diningLight = new DiningLight();
    public void lightOn(){
        livingRoomLight.on();
        hallLight.on();
        diningLight.on();
    }
    public void lightOff(){
        livingRoomLight.off();
        hallLight.off();
        diningLight.off();
    }
}
interface Light {
    void on();
    void off();
}
/**
 * 客厅灯 
 */
class LivingRoomLight implements Light{
    @Override
    public void on() {
        System.out.println("打开客厅灯");
    }
    @Override
    public void off() {
        System.out.println("关闭客厅灯");
    }
}
/**
 * ⾛廊灯 
 */
class HallLight implements Light{
    @Override
    public void on() {
        System.out.println("打开⾛廊灯");
    }
    @Override
    public void off() {
        System.out.println("关闭⾛廊灯");
    }
/**
 * 餐厅灯 
 */
class DiningLight implements Light{
    @Override
    public void on() {
        System.out.println("打开餐厅灯");
    }
    @Override
    public void off() {
        System.out.println("关闭餐厅灯");
    }
}

门面模式的优点

  • 减少了系统的相互依赖,实现了客户端与子系统的耦合关系,这使得子系统的变化不会影响到调用它的客户端;
  • 提高了灵活性,简化了客户端对子系统的使用难度,客户端无需关心子系统的具体实现方式,而只需要和门面对象交互即可。
  • 提高了安全性,可以灵活设定访问权限,不在门面对象中开通方法,就无法访问
2.2.2 SLF4J框架介绍

SLF4J就是其他日志框架的门面.SLF4J可以理解为是提供日志服务的统一API接口,并不涉及到具体的

日志逻辑实现.

在不引入日志门面时,若项目使用如 log4j 的日志框架,又依赖使用其他日志框架(如 Apache Active MQ 依赖 logback ),需加载额外日志框架。

但这样会出现问题:多日志框架共存要维护多套配置文件;更换日志框架需修改代码,易引发冲突;引入用多套日志的第三方框架,也得维护多套配置 。

简单来说,就是不引入日志门面时,项目因依赖引入多个日志框架会带来配置维护复杂、更换框架成本高的问题 。

引入门面日志框架之后,应用程序和日志框架(框架的具体实现)之间有了统一的API接口(门面日志框架实现),此时应用程序只需要维护一套日志文件配置,且当底层实现框架改变时,也不需要更改应用程序代码.

引入门面日志框架之后,应用程序和日志框架(框架的具体实现)之间有了统一的API接口(门面日志框架实现),此时应用程序只需要维护一套日志文件配置,且当底层实现框架改变时,也不需要更改应用程序代码.

SLF4J就是这个日志门面.

总的来说,SLF4J使你的代码独立于任意一个特定的日志API,这是一个对于开发API的开发者很好的思想.

2.3 日志级别

日志级别代表着日志信息对应问题的严重性,为了更快的筛选符合目标的日志信息,试想一下这样的场景,假设你是一家2万人公司的老板,如果每个员工的日常工作和琐碎的信息都要反馈给你,那你一定无暇顾及,于是就有了组织架构,而组织架构就会分级,有很多的级别设置,如下图所示:

有了组织架构之后,就可以逐级别汇报消息了,例如:组员汇报给组长,组长汇报给研发一组,研发一组汇报给Java研发,等等依次进行汇报

日志级别大概是同样的道理,有了日志级别之后就可以过滤自己想看到的信息了,比如只关注error级别的,就可以根据级别过滤出来error级别的日志信息,节约开发者的信息筛选时间.

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

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

日志级别通常和测试人员的Bug级别没有关系. 日志级别是开发人员设置的,用来给开发人员看的,日志级别的正确设置,也与开发人员的工作经验有关,如果开发人员把error级别的日志设置成了info,就很有可能会影响开发人员对项目运行情况的判断.出现error级别的日志信息较多时,可能也没有任何问题,测试的bug级别更多是依据现象和影响范围来判断

2.4 日志级别的使用

SpringBoot默认的日志框架是Logback,Logback没有FATAL级别,它被映射到ERROR.

出现fatal日志,表示服务已经出现了某种程度的不可用,需要需要系统管理员紧急介入处理,通常情况下,一个进程生命周期中应该最多只有一次FATAL记录。

代码语言:javascript
复制
@RestController
@RequestMapping("/logger")
public class LoggerController {
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/print")
    public String print() {
        logger.trace("trace");
        logger.debug("debug");
        logger.info("info");
        logger.warn("warn");
        logger.error("error");
        return "打印日志";
    }
}

结果发现,只打印了info,Warn和error级别的日志

这与日志级别的配置有关,日志的输出级别默认是info级别,所以只会打印大于等于此级别的日志,也就是info, warn和error.

2.5 日志配置

代码语言:javascript
复制
logging:
  level:
    root: debug
代码语言:javascript
复制
#针对路径设置级别
logging:
  level:
    root: debug
    com:
      example:
        captchademo:
          controller: trace
2.5.2 日志持久化

以上的日志都是输出在控制台上的,然而在线上环境中,我们需要把日志保存下来,以便出现问题之后追溯问题,把日志保存下来就叫持久化。内存->硬盘

日志持久化有两种方式

  1. 配置日志文件名
  2. 配置日志的存储目录
代码语言:javascript
复制
logging.file.name=logger/springboot.log
代码语言:javascript
复制
#设置日志文件的文件名
logging:
  file:
    name:logger/springboot.log

设置配置文件的保存路径

若没有该文件夹会自动创建

(不能设置文件名称,它会当成一级一级的文件夹)

代码语言:javascript
复制
# 设置⽇志⽂件的⽬录 
logging:
  file:
    path: D:/temp

logging.file.namelogging.file.path两个都配置的情况下,只生效其一,以logging.file.name为准.

2.5.3 配置日志文件分割

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

当然,日志框架也帮我们考虑到了这一点,所以如果不进行配置,就走自动配置 默认日志文件超过10M就进行分割

配置项

说明

默认值

logging.logback.rollingpolicy.file - name - pattern

日志分割后的文件名格式

${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz

logging.logback.rollingpolicy.max - file - size

日志文件超过这个大小就自动分割

10MB

配置日志文件分割:

Properties配置

代码语言:javascript
复制
logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i logging.logback.rollingpolicy.max-file-size=1KB 

yml配置

代码语言:javascript
复制
logging:
  logback:
    rollingpolicy:
      max-file-size: 1KB
      file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
  1. 日志文件超过1KB就分割(设置1KB是为了更好展示.企业开发通常设置为200M,500M等,此处没有明确标准)
  2. 分割后的日志文件名为:日志名.日期索引
2.5.4 配置日志格式

打印日志的格式,也是支持配置的.支持控制台和日志文件分别设置

配置项

说明

默认值

logging.pattern.console

控制台日志格式

%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

logging.pattern.file

日志文件的日志格式

%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39}: %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

设置控制台颜色

代码语言:javascript
复制
logging.pattern.console='%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'
代码语言:javascript
复制
logging:
  pattern:
    console: '%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'
    file: '%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'
  • logging.pattern.console:指定 “控制台日志” 的格式。
  • 日志格式语法(以 % 开头的是占位符):
    • %d{yyyy-MM-dd HH:mm:ss.SSS}:日志产生的时间(精确到毫秒)。
    • %c:日志所属的类的全限定名(比如 com.example.demo.UserController)。
    • %M:日志所在的方法名(比如 getUser)。
    • %L:日志所在的代码行号。
    • [%thread]:产生日志的线程名(比如 http-nio-8080-exec-1)。
    • %m:日志的具体内容(比如 用户登录成功)。
    • %n:换行符(让每条日志占一行)。

2.6 更简单的日志输出

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

  1. 添加lombok框架支持
  2. 使用@slf4j注解输出日志。
代码语言:javascript
复制
@Slf4j
@RestController
@RequestMapping("/logger")
public class LoggerController2 {
    @RequestMapping("/print")
    public String print() {
        log.trace("trace");
        log.debug("debug");
        log.info("info");
        log.warn("warn");
        log.error("error");
        return "打印日志";
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.日志概述
    • 1.1 日志的用途
  • 2.日志使用
    • 2.1 打印日志
      • 2.1.1 在程序中得到日志对象
      • 2.1.2 使用日志对象打印日志
    • 2.2 日志框架
      • 2.2.1 门面模式(外观模式)
      • 2.2.2 SLF4J框架介绍
    • 2.3 日志级别
    • 2.4 日志级别的使用
    • 2.5 日志配置
      • 2.5.2 日志持久化
      • 2.5.3 配置日志文件分割
      • 2.5.4 配置日志格式
    • 2.6 更简单的日志输出
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档