


专栏:JavaEE 进阶跃迁营
个人主页:手握风云
目录
[1.1. 学习日志的原因](#1.1. 学习日志的原因)
[1.2. 日志的核心用途](#1.2. 日志的核心用途)
[2.1. 打印日志](#2.1. 打印日志)
[2.2. 日志框架](#2.2. 日志框架)
[1. 门面模式](#1. 门面模式)
[2. SLF4J 框架](#2. SLF4J 框架)
[2.3. 日志格式说明](#2.3. 日志格式说明)
[2.4. 日志级别](#2.4. 日志级别)
[1. 日志级别的分类](#1. 日志级别的分类)
[2. 日志级别的使用](#2. 日志级别的使用)
[2.5. 日志配置](#2.5. 日志配置)
[1. 配置日志级别](#1. 配置日志级别)
[2. 日志持久化](#2. 日志持久化)
[3. 配置日志文件分割](#3. 配置日志文件分割)
一、日志概述
1.1. 学习日志的原因
日志是程序开发与维护中的基础工具,从 JavaSE 阶段就通过 System.out.print 打印日志以定位问题、分析程序运行过程,Spring 学习中也常依赖控制台日志排查问题。但随着项目复杂度提升,System.out.print 无法满足更高需求(如需留存用户操作记录以符合审计要求、持久化日志用于后续数据分析等),因此需引入专业日志框架,实现更灵活、全面的日志管理。
1.2. 日志的核心用途
-
系统监控作为成熟系统的标配能力,日志可记录系统运行状态(如各方法的响应时间、响应状态),通过分析日志数据设置规则:当指标超过阈值(如异常关键字数量达标)时触发报警,及时发现系统异常。
-
数据采集采集的数据可支撑业务优化与智能决策,主要分为两类场景:
- 数据统计:记录页面浏览量(PV)、访客量(UV)、用户点击量等,基于数据优化公司运营策略;
- 推荐排序:在购物、广告、新闻等领域,通过日志记录用户浏览历史、页面停留时长等行为数据,供算法人员训练推荐模型,实现精准推荐。

-
日志审计为满足国家政策法规与行业标准对系统安全的要求,日志可追踪关键操作与风险行为:
- 溯源操作:如运营系统中数据被删除 / 修改时,通过日志明确操作人,避免责任追溯困难;
- 防范违规:记录内部人员对敏感信息(如客户信息)的访问行为,若出现频繁查询等异常操作可触发报警,防止信息泄露。
二、日志的使用
SpringBoot 默认集成 SLF4J(日志门面)+ Logback(日志实现),无需额外引入核心依赖即可使用;日志打印到控制台,包含 6 类结构化信息(时间日期、日志级别、进程 ID、线程名、Logger 名、日志内容)。

System.out 仅能打印简单文本,缺少上述结构化信息,无法实现分级筛选、格式定制等高级需求。
2.1. 打印日志
打印日志分为两个步骤:1. 在程序中获取日志对象;2. 使用日志对象输出内容。注意 Logger 和 LoggerFactory 都是来自于 org.slf4j 包下的。

java
package com.yang.test2_2_1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/logger")
@RestController
public class LoggerController {
// 获取日志对象
private Logger logger = LoggerFactory.getLogger("abc");
@RequestMapping("/print")
public String print() {
System.out.println("打印日志");
logger.info("打印日志");
return "1";
}
}

2.2. 日志框架

SLF4J 不同于其他日志框架,它不是一个真正的日志实现,而是一个抽象层,对日志框架制定的一种规范,标准,接口。所有SLF4J并不能独立使用,需要和具体的日志框架配合使用。比如我们在网购时,打开的界面就属于门面,当我们下单之后,电商平台会通知买家进行订单处理,发货等,这就属于实现。
1. 门面模式
门面模式 (Facade Pattern) 又称为外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。其主要特征是定义了一个高层接口,让子系统更容易使用。

门面模式的实现:场景,回家,我们会开各个屋的灯;离开家时, 会关闭各个屋的灯。如果家里设置一个总开关,来控制整个屋的灯就会很方便。
如果按照以前的面向对象思维来设计:
java
package com.yang.test2_2_2.facade;
public class FacadeMain {
public static void main(String[] args) {
BedRoomLight light1 = new BedRoomLight();
BathRoomLight light2 = new BathRoomLight();
light1.on();
light2.on();
light1.off();
light2.off();
}
}
java
package com.yang.test2_2_2.facade;
public class BedRoomLight implements Light {
@Override
public void on() {
System.out.println("打开卧室的灯");
}
@Override
public void off() {
System.out.println("关闭卧室的灯");
}
}
java
package com.yang.test2_2_2.facade;
public class BathRoomLight implements Light {
@Override
public void on() {
System.out.println("浴室灯打开");
}
@Override
public void off() {
System.out.println("浴室灯关闭");
}
}
java
package com.yang.test2_2_2.facade;
public interface Light {
void on();
void off();
}
采用门面设计模式实现:
java
package com.yang.test2_2_2.facade;
public class FacadeLight {
private BedRoomLight light1;
private BathRoomLight light2;
public FacadeLight() {
light1 = new BedRoomLight();
light2 = new BathRoomLight();
}
public void lightOn() {
light1.on();
light2.on();
}
public void lightOff() {
light1.off();
light2.off();
}
}
门面模式的优点:
- 减少了系统的相互依赖,实现了客户端与子系统的耦合关系,这使得子系统的变化不会影响到调用它的客户端;
- 提高了灵活性,简化了客户端对子系统的使用难度,客户端无需关心子系统的具体实现方式,而只需要和门面对象交互即可;
- 提高了安全性,可以灵活设定访问权限,不在门面对象中开通方法,就无法访问。
2. SLF4J 框架
SLF4J(Simple Logging Facade for Java)并非真正的日志实现框架,而是日志门面(Logging Facade)------ 即对日志框架制定的统一 API 接口规范,自身无法独立使用,必须与具体的日志实现框架(如 log4j、logback 等)配合才能生效。
如果不引入日志门面,当存在多日志框架共存场景(如项目自身用 log4j,依赖的第三方框架用 logback)时,会面临以下问题:多套配置文件维护;更换框架成本高;

引入 SLF4J 作为日志门面后,应用程序与具体日志实现框架之间通过统一 API 交互,可解决上述问题,简化配置、统一第三方适配。

2.3. 日志格式说明
Spring Boot 日志输出包含固定的核心元素,这些元素能清晰呈现日志的上下文信息,帮助开发者快速定位问题、分析程序运行状态。
| 元素序号 | 元素名称 | 说明 |
|---|---|---|
| 1 | 时间日期 | 精确到毫秒,用于记录日志产生的具体时间,便于时间线追溯问题 |
| 2 | 日志级别 | 标识日志信息的严重性,可选值:ERROR、WARN、INFO、DEBUG、TRACE(无 FATAL,Logback 中映射为 ERROR) |
| 3 | 进程 ID | 日志所属应用进程的唯一标识,多实例部署时可区分不同进程的日志 |
| 4 | 线程名 | 日志产生时的线程名称,用于多线程场景下定位线程相关问题 |
| 5 | Logger 名 | 通常为源代码的类名,用于直接定位日志所属的业务类或框架类 |
| 6 | 日志内容 | 开发者自定义或框架自动生成的具体日志信息,记录程序运行细节或错误描述 |
2.4. 日志级别
日志级别代表着日志信息对应问题的严重性,为了更快的筛选符合目标的日志信息。
1. 日志级别的分类
| 日志级别 | 严重程度 | 核心含义与使用场景 |
|---|---|---|
| FATAL | 最高 | 致命信息,代表需立即处理的系统级错误,通常意味着服务已出现某种程度的不可用(如核心服务崩溃),一个进程生命周期中最多应只出现一次该级别日志。 |
| ERROR | 较高 | 错误信息,代表级别较高的错误,但不影响系统整体继续运行(如单个接口调用失败、数据查询异常),需开发人员关注并排查问题根源。 |
| WARN | 中等 | 警告信息,代表不影响功能使用,但需注意的潜在问题(如配置项未显式设置、使用即将废弃的 API),提醒开发人员关注可能的风险点。 |
| INFO | 较低 | 普通信息,用于记录应用程序正常运行时的关键状态(如系统启动完成、请求处理成功、服务连接建立),反映程序的常规运行流程。 |
| DEBUG | 更低 | 调试信息,用于开发阶段打印问题排查所需的关键细节(如变量值、方法调用链路、参数传递情况),帮助开发人员定位代码逻辑问题。 |
| TRACE | 最低 | 追踪信息,比 DEBUG 更细粒度的信息事件(如代码行级别的执行轨迹),除非有特殊追踪需求,否则建议用 DEBUG 级别替代,避免日志信息过度冗余。 |

2. 日志级别的使用
java
package com.yang.test2_2_3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/logger")
public class LoggerController {
private 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 "1";
}
}
这里是没有 fatal 级别的方法,它被映射到了 error。出现了 fatal 日志,就说明服务已经出现了某种程度的不可用,需要系统管理员紧急介入。比如,如果公司里面出现断电,或者磁盘满了,此时就不需要汇报,可能用户已经给客服打电话了。
运行程序,会发现只打印了 info、warn 和 error 级别的日志。这与日志的级别有关,日志输出默认级别为 info 级别,所以只会输出大于等于此级别的日志。

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

2. 日志持久化
日志持久化指将原本仅输出到控制台的日志保存到文件中,核心目的是线上环境问题追溯------ 避免控制台日志随程序重启或会话结束丢失,便于后续排查故障、分析问题根源。日志持久化通过配置文件指定 "日志文件名" 或 "日志存储目录" 实现。

java
logging:
file:
name: log.log

刷新下文件目录,会多出一个 log.log 的文件,我们再次启动程序也不会消失,这样就做到了持久化。

java
logging:
file:
path: logger2/
再次启动,刷新,会多出一个文件 logger2,里面有一个 spring.log 的文件。

3. 配置日志文件分割
如果我们的日志都放在一个文件中,随着项目的运行,日志文件会越来越大,需要对日志文件进行分割。当然,日志框架也帮我们考虑到了这一点,所以如果不进行配置,就走自动配置 默认日志文件超过10M就进行分割。

java
logging:
logback:
rollingpolicy:
max-file-size: 1KB