日志体系
本教程共 48 篇 · 第 14 篇 · 更新于 2026-08-13 · 约 4 分钟阅读
本节目标:搞懂 Spring Boot 的日志默认配置,学会调级别、写文件、自定义格式,还能换成 log4j2。
默认日志框架
Spring Boot 内部用 Commons Logging 做抽象,具体实现默认是 Logback。
用 Starter 启动的项目,Logback 已经就位,一行配置都不用写。
它还能把 JUL、Log4J、SLF4J 的日志都路由过来,统一输出。
代码里写日志,用的是 SLF4J 门面 API。门面像插座转换头:不管背后是哪个日志框架,你只插一个口。换底层框架不用改代码。
默认日志格式
启动时能看到类似这样的输出:
2026-06-10T16:33:40.717Z INFO 53358 --- [hello-app] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
从左到右各段含义:
- 日期时间,毫秒精度。
- 日志级别。
- 进程 ID。
---分隔符。- 应用名,来自
spring.application.name。 - 线程名。
- 日志器名,通常是类名缩写。
- 日志内容。
级别顺序:TRACE < DEBUG < INFO < WARN < ERROR。
NoteLogback 没有 FATAL 级别,FATAL 会映射成 ERROR。
在代码里打日志
SLF4J 的标准姿势:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
private static final Logger log = LoggerFactory.getLogger(HelloController.class);
@GetMapping("/hello")
public String hello(String name) {
log.info("收到请求,参数 name={}", name);
log.debug("这里只有调试时才输出");
return "hello " + name;
}
}
{} 是占位符,参数会自动拼进去。别用字符串拼接,性能差一截。
调整日志级别
配置文件里用 logging.level. 前缀:
logging:
level:
root: info
org.springframework.web: debug
com.example.demo: warn
root 是全局兜底级别。包名越具体,优先级越高。
也可以单独调某个类:
logging:
level:
com.example.demo.HelloController: trace
环境变量也能调,包级生效:
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG
Tip线上排查问题,临时调高某个包的级别,不用改代码重新发版。改配置重启即可。
快速调试模式
不想一个个配级别?启动时加 --debug:
java -jar hello-app.jar --debug
这会把核心框架(容器、Spring Boot 自身)的日志调到 DEBUG,顺带打印的条件报告见 §6。
--trace 更狠,连 Hibernate 的 SQL 生成都输出。
配置文件里写 debug: true 效果一样。
输出到文件
默认只打控制台,不打文件。想落盘,配置两个键:
logging:
file:
name: logs/myapp.log
或者只给目录,文件名固定为 spring.log:
logging:
file:
path: /var/log/myapp
两个都写时,file.name 生效,file.path 被忽略。
文件默认 10MB 滚动一次。滚动策略可以调:
logging:
logback:
rollingpolicy:
max-file-size: 20MB
max-history: 14
total-size-cap: 1GB
max-file-size:单文件多大开始滚动。max-history:保留多少个归档文件。total-size-cap:归档总大小上限。
自定义日志格式
不想用默认格式?改 pattern:
logging:
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n"
%d 时间、%level 级别、%thread 线程、%logger 日志器名、%msg 消息、%n 换行。
支持 ANSI 颜色,比如让级别按颜色显示:
logging:
pattern:
console: "%clr(%5p) %clr([%thread]){yellow} %clr(%logger{36}){cyan} - %msg%n"
日志分组
想把一组相关包一起调级别?先定义分组:
logging:
group:
tomcat: org.apache.catalina,org.apache.coyote,org.apache.tomcat
然后一条命令调整个组:
logging:
level:
tomcat: trace
内置分组直接用:web 涵盖 Spring Web 全家,sql 涵盖 JDBC 和 Hibernate SQL。
完整自定义:logback-spring.xml
配置文件的键不够用时,用 Logback 自己的 XML。放 src/main/resources/logback-spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/myapp.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/myapp-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
<logger name="com.example.demo" level="DEBUG"/>
</configuration>
Note文件名要用
logback-spring.xml,别用logback.xml。带-spring的变体能被 Spring Boot 完全接管,支持 profile 等扩展。
切换到 log4j2
换框架只要动依赖。先排除默认的 Logback:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
再放一个 src/main/resources/log4j2-spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="RollingFile"
fileName="logs/myapp.log"
filePattern="logs/myapp-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<DefaultRollOverStrategy max="7"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
代码不用改。SLF4J 门面把差异挡住了。
Tip只有特殊团队要求(如现有日志采集体系基于 log4j2)才值得切换。默认 Logback 对绝大多数项目够用。
结构化日志(JSON)
日志要送给日志平台(ELK、Loki 等)时,JSON 格式比文本好解析。
Spring Boot 内置支持三种 JSON 格式:
ecs:Elastic Common Schema。gelf:Graylog 格式。logstash:Logstash 格式。
开启方式一行配置:
logging:
structured:
format:
console: ecs
file: ecs
输出会变成 JSON 行:
{"@timestamp":"2026-08-13T10:00:00.000Z","log.level":"INFO","message":"Tomcat started on port 8080","service.name":"hello-app"}
采集端按字段过滤、聚合都很方便。
MDC 上下文信息
想给每行日志带上请求 ID、用户 ID?用 MDC。
MDC 是日志框架的上下文存储,ThreadLocal 实现,同线程内共享:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
private static final Logger log = LoggerFactory.getLogger(HelloController.class);
@GetMapping("/hello")
public String hello(String userId) {
MDC.put("userId", userId);
try {
log.info("处理用户请求");
return "hello";
} finally {
MDC.remove("userId");
}
}
}
配合 logging.pattern.level 把 MDC 值打出来:
logging:
pattern:
level: "user:%X{userId} %5p"
WarningMDC 用完必须清理。不 remove 的话,线程池复用时旧值会串到下一个请求。
日志性能习惯
日志写得多,性能就掉得快。三个习惯值得养成:
- 参数用
{}占位符,别用字符串拼接。 - DEBUG 日志包一层级别判断,参数构造开销大时尤其重要。
if (log.isDebugEnabled()) {
log.debug("用户列表: {}", expensiveToString());
}
- 高频路径只打 INFO 及以下,别什么都 DEBUG。
生产环境默认 INFO,打不进文件的就是没发生。
小结
- 默认 Logback + SLF4J,开箱即用。
logging.level.调级别,--debug快速调试。logging.file.name落盘,默认 10MB 滚动。logging.pattern.*自定义格式。- 复杂需求用
logback-spring.xml。 - 结构化日志一行配置输出 JSON,MDC 携带上下文。
- 换 log4j2 只需改依赖和配置文件。