bigywater.tech
Spring · 81

日志:Logback 配置、分组、滚动与运行时改级别

日志怎么按包调级别?logging.group 和单独配置谁优先?日志文件怎么滚动、max-history 到底管什么?线上能不能不重启就开 DEBUG?logback.xml 和 logback-spring.xml 差在哪?这篇在 Spring Boot 4.0.8 上逐项实测。

9 → 1064
默认启动输出 9 行日志,root 调到 DEBUG 之后 1064 行
TRACE 盖过 WARN
logging.group.mine 设成 TRACE,压过了对 demo.b 单独写的 WARN
204
POST /actuator/loggers/demo 改成 DEBUG 之后不重启就生效

格式与级别

实测 · 本机执行输出
  默认(root=INFO):启动到端口可连接一共输出 9 行;第 1 行:
    2026-10-20T10:59:45.770+08:00  INFO 59726 --- [           main] demo.Main                                : Starting Main using Java 21.0.12.1 with PID 59726 (<jtmp>/x81/out started by w in <…
    最后一行:2026-10-20T10:59:46.461+08:00  INFO 59726 --- [           main] demo.Main                                : Started Main in 0.872 seconds (process running for 1.04)
  logging.level.root=DEBUG:启动共 1064 行
  logging.level.org.springframework=DEBUG:启动共 1010 行
  logging.level.root=TRACE:启动共 4120 行
  logging.level.root=WARN:启动共 0 行
  logging.pattern.console 自定义之后第 1 行:10:59:53 INFO  [main] demo.Main - Starting Main using Java 21.0.12.1 with PID 60249 (<jtmp>/x81/out started by w in <jtmp>/x81_wd)
  logging.structured.format.console=ecs:一行 JSON,字段 ['@timestamp', 'ecs', 'log', 'message', 'process', 'service', 'tags'](共 7 个)
  logging.structured.format.console=logstash:一行 JSON,字段 ['@timestamp', '@version', 'level', 'level_value', 'logger_name', 'message', 'tags', 'thread_name'](共 8 个)
  logging.structured.format.console=gelf:一行 JSON,字段 ['_level_name', '_log_logger', '_process_pid', '_process_thread_name', 'level', 'short_message', 'timestamp', 'version'](共 8 个)

默认 INFO,启动 9 行;root=DEBUG 是 1064 行;有 ecs、logstash、gelf 三种结构化输出。

分组

实测 · 本机执行输出
  logging.level.web=DEBUG:org.springframework.web configured=DEBUG effective=DEBUG
  logging.level.web=DEBUG:org.springframework.http configured=DEBUG effective=DEBUG
  logging.level.web=DEBUG:org.springframework.web.servlet.DispatcherServlet configured=null effective=DEBUG
  logging.level.web=DEBUG:org.springframework.boot configured=null effective=INFO
  logging.level.web=DEBUG:demo configured=null effective=INFO
  logging.level.sql=DEBUG:org.hibernate.SQL configured=DEBUG effective=DEBUG
  logging.level.sql=DEBUG:org.springframework.jdbc.core configured=DEBUG effective=DEBUG
  logging.level.sql=DEBUG:org.jooq.tools.LoggerListener configured=DEBUG effective=DEBUG
  logging.group.mine=demo.a,demo.b + level.mine=TRACE + level.demo.b=WARN:demo.a configured=TRACE effective=TRACE
  logging.group.mine=demo.a,demo.b + level.mine=TRACE + level.demo.b=WARN:demo.b configured=TRACE effective=TRACE
  logging.group.mine=demo.a,demo.b + level.mine=TRACE + level.demo.b=WARN:demo.c configured=null effective=INFO
  logging.group.mine=demo.a,demo.b + level.mine=TRACE + level.demo.b=WARN:demo.a.sub configured=null effective=TRACE
  logging.level.demo=DEBUG、demo.x=ERROR 时 /log 的输出(按 logger 名分):
    ERROR 60918 --- [nio-9614-exec-2] demo.x                                   : error 行
    DEBUG 60918 --- [nio-9614-exec-3] demo.y                                   : debug 行
    INFO 60918 --- [nio-9614-exec-3] demo.y                                   : info 行
    WARN 60918 --- [nio-9614-exec-3] demo.y                                   : warn 行
    ERROR 60918 --- [nio-9614-exec-3] demo.y                                   : error 行

内置 web、sql 分组;自定义分组的级别盖过单独写的子配置。

文件与滚动

实测 · 本机执行输出
  logging.file.name=logs/app.log,写 10 行:logs/app.log 3624 字节
  logging.file.path=logs(不写文件名):logs/spring.log 3624 字节
  max-file-size=4KB、max-history=3,写 300 行 × 约 100 字符 + 前缀:生成 17 个文件:
    logs/app.log  1430 字节
    logs/app.log.2026-10-20.0.gz  714 字节
    logs/app.log.2026-10-20.1.gz  196 字节
    logs/app.log.2026-10-20.10.gz  180 字节
    logs/app.log.2026-10-20.11.gz  201 字节
    logs/app.log.2026-10-20.12.gz  196 字节
    logs/app.log.2026-10-20.13.gz  191 字节
    logs/app.log.2026-10-20.14.gz  184 字节
    logs/app.log.2026-10-20.15.gz  185 字节
    logs/app.log.2026-10-20.2.gz  199 字节
    logs/app.log.2026-10-20.3.gz  194 字节
    logs/app.log.2026-10-20.4.gz  199 字节
    logs/app.log.2026-10-20.5.gz  187 字节
    logs/app.log.2026-10-20.6.gz  198 字节
    logs/app.log.2026-10-20.7.gz  193 字节
    logs/app.log.2026-10-20.8.gz  201 字节
    logs/app.log.2026-10-20.9.gz  194 字节
  file-name-pattern=logs/app-%d{yyyyMMdd}.%i.log(不带 .gz):15 个文件:logs/app-20261020.10.log 4199 字节; logs/app-20261020.11.log 4199 字节; logs/app-20261020.12.log 4199 字节; logs/app-20261020.13.log 4199 字节; logs/app-20261020.14.log 4199 字节; logs/app-20261020.15.log 4199 字节; logs/app-20261020.2.log 4180 字节; logs/app-20261020.3.log 4180 字节; logs/app-20261020.4.log 4180 字节; logs/app-20261020.5.log 4185 字节; logs/app-20261020.6.log 4199 字节; logs/app-20261020.7.log 4199 字节; logs/app-20261020.8.log 4199 字节; logs/app-20261020.9.log 4199 字节; logs/app.log 1430 字节

logging.file.name / path;按大小滚动,默认 gz 压缩;max-history 按天保留。

运行时改级别

实测 · 本机执行输出
  初始:GET /actuator/loggers/demo.rt → 404 ;/log?n=demo.rt 输出 debug 行数 0
  POST /actuator/loggers/demo {"configuredLevel":"DEBUG"} → 204
  之后:GET /actuator/loggers/demo.rt → {"effectiveLevel":"DEBUG"};/log?n=demo.rt 输出 debug 行数 1(没有重启)
  POST {"configuredLevel":null} → 204;GET /actuator/loggers/demo → {"effectiveLevel":"INFO"};debug 行数 0
  对分组 web 发 POST /actuator/loggers/web {"configuredLevel":"TRACE"} → 204;GET /actuator/loggers/org.springframework.web → {"configuredLevel":"TRACE","effectiveLevel":"TRACE"}
  非法级别 LOUD → 400

POST /actuator/loggers/{名字},包括分组,立即生效,null 恢复。

logback 配置文件

实测 · 本机执行输出
  logback-spring.xml,profile=dev:/log?n=demo.p 的输出 → [DEV-ONLY] DEBUG debug 行 | [DEFAULT] DEBUG debug 行 | [DEV-ONLY] INFO info 行 | [DEFAULT] INFO info 行 | [DEV-ONLY] WARN warn 行 | [DEFAULT] WARN warn 行 | [DEV-ONLY] ERROR error 行 | [DEFAULT] ERROR error 行
  logback-spring.xml,profile=无:/log?n=demo.p 的输出 → [DEFAULT] INFO info 行 | [DEFAULT] WARN warn 行 | [DEFAULT] ERROR error 行
  logback.xml,profile=dev:/log?n=demo.p 的输出 → [DEV-ONLY] DEBUG debug 行 | [DEFAULT] DEBUG debug 行 | [DEV-ONLY] INFO info 行 | [DEFAULT] INFO info 行 | [DEV-ONLY] WARN warn 行 | [DEFAULT] WARN warn 行 | [DEV-ONLY] ERROR error 行 | [DEFAULT] ERROR error 行
  logback.xml,profile=无:/log?n=demo.p 的输出 → [DEFAULT] INFO info 行 | [DEFAULT] WARN warn 行 | [DEFAULT] ERROR error 行

springProfile 在 logback.xml 与 logback-spring.xml 里都生效。

分步演示

日志
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动。被测应用是 spring-boot-starter-webmvc 加 spring-boot-starter-actuator 的单个程序(Logback 随 starter 来),日志取自进程的标准输出或写入的文件;每个场景一个独立 JVM;滚动用 /burst 接口写入固定行数;运行时改级别只暴露 loggers 端点,没有做认证
    • 没有验证:按天滚动(跨过午夜);默认 10MB 的滚动大小与 total-size-cap 实际触发的删除;logging.config 指向自定义文件;Log4j2 作为底层的行为;异步 appender;MDC 与链路 id;日志的性能开销;修改的日志级别重启后是否保留(按常识不保留,没有再跑);springProfile 在 logback.xml 里生效的原因
    京ICP备2026067502号-1京公网安备11010502063487号