相信大家在开发过程中很多地方都需要打印输出来进行调试。我刚开始学Java的时候,还习惯使用System.out.println来打印记录信息。但是很多时候会发现其实并不方便,比如我需要记录线程信息,记录一些别的啥信息。都不方便,最关键的是,当项目上线之后,日志一般需要专门记录,你这样输出肯定不可以的。

日志门面 日志实现
JCL(Jakarta Commons Logging)
SLF4j(Simple Logging for Java)
jboss-logging
Log4jJUL(java.util.logging)
Log4j2Logback

感兴趣的日志框架起源的与关系的可以区看这个视频:https://www.bilibili.com/video/BV1gW411W76m 的21至27集

1. 简介

  1. Spring使commons-logging 作为内部日志,但底层实现是开放的。可对接其他日志框架。
    1. Spring5及以commons-logging 被spring自己写了。
  2. 支持jul log4j logback 。Spring Boot提供了默认的控制台输出配置,也可以配置输出为文件。
  3. logback 是默认使用。(在引入其他框架的时候注意检查,不然启动会警告)
  4. 虽然日志框架很多,但是我们不用担心,使用Spring Boot的默认配置就可以工作得很好。

Spring Boot是如何把日志默认配置好的

  1. 每个starter 场景,都会导入一个核心的场景 spring-boot-starter
  2. 核心场景引入日志的所有功能 spring-boot-starter-logging
  3. 默认使用了 logback+slf4j 组合作为默认底层日志
  4. 日志是系统统一启动就要用 , xxxAutoConfiguration 是系统启动好了之后放好的组件,后面才会使用。
  5. 日志是利用监听器机制 配置好的 。ApplicationListener

日志格式

默认的日志格式如下:

2025-09-12T20:46:34.829+08:00  INFO 17872 --- [han_picture] [  restartedMain] c.h.han_picture.HanPictureApplication    : Starting HanPictureApplication using Java 21.0.8 with PID 17872 (/home/Hanserwei/IdeaProjects/han_picture/target/classes started by Hanserwei in /home/Hanserwei/IdeaProjects/han_picture)
2025-09-12T20:46:34.831+08:00  INFO 17872 --- [han_picture] [  restartedMain] c.h.han_picture.HanPictureApplication    : The following 1 profile is active: "local"
2025-09-12T20:46:34.854+08:00  INFO 17872 --- [han_picture] [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable

默认输出格式:

  • 时间和日期:毫秒级别精度
  • 日志级别: ERROR ,WARN , INFO , DEBUG , TRACE
  • 进程ID
  • --- :消息分割符
  • 线程名:使用[] 包含
  • Logger名:通常是产生日志的类名
  • 消息:日志记录的内容

注意:logback没有 FATAL 级别,对应的是 ERROR

默认值:参照: spring-boot 包 additional-spring-configuration-metadata.json 文件

默认输出格式值: %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.S SSXXX}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magent a} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cya n} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

可修改为: '%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} == => %msg%n'

记录日志

有两个方式:

Logger logger = LoggerFactory.getLogger(getClass());

或者直接使用注解

@Slfj

日志级别

  • 由高到低 ALL,TRACE, DEBUG, INFO, WARN, ERROR,FATAL,OFF
    • 只会打印指定级别及以上级别的日志
    • ALL:打印所有日志
    • TRACE:追踪框架详细流程日志,一般不使用
    • DEBUG:开发调试细节日志
    • INFO:关键、感兴趣信息日志
    • WARN:警告但不是错误的信息日志,比如:版本过时
    • ERROR:业务错误日志,比如出现各种异常
    • FATAL:致命错误日志,比如jvm系统崩溃
    • OFF:关闭所有日志记录
  • 不指定级别的所有类,都使用root指定的级别作为默认级别
  • SpringBoot日志默认级别是 INFO
  1. 在 application.properties/yaml中配置 logging.level.=指定日志级别
  2. level可取值范围: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, or OFF ,定义 在 LogLevel 类中
  3. root 的 logger-name叫root,可以配置 logging.level.root=warn,代表所有未指定日志级别都 使用 root 的 warn 级别

日志分组

比较有用的技巧是: 将相关的logger分组在一起,统一配置。SpringBoot 也支持。比如:Tomcat 相关的日志统一设 置。

logging:
  group:
    name: com.hanserwei.han_picture

SpringBoot 预定义两个组

Name Loggers
web org.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans
sql org.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener

文件输出

SpringBoot 默认只把日志写在控制台,如果想额外记录到文件,可以在application.properties中 添加logging.file.name or logging.file.path配置项。当然你写在yaml文件也是可以的。

logging.file.name logging.file.path 示例 效果
未指定 未指定 仅控制台输出
指定 未指定 my.log 写入指定文件
未指定 指定 /var/log 写入指定目录
指定 指定 以logging.file.name为准

文件归档和滚动切割

归档:每天的日志单独存到一个文档中

切割:每个文件10MB,超过大小切割为另一个文件

  1. 每天的日志应该独立分割出来存档。如果使用logback(SpringBoot 默认整合),可以通过 application.properties/yaml文件指定日志滚动规则。
  2. 如果是其他日志系统,需要自行配置(添加log4j2.xml或log4j2-spring.xml)
  3. 支持的滚动规则设置如下
配置项 描述
logging.logback.rollingpolicy.file-namepattern 日志存档的文件名格式(默认值: ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz)
logging.logback.rollingpolicy.clean-historyon-start 应用启动时是否清除以前存档(默认值: false)
logging.logback.rollingpolicy.max-file-size 存档前,每个日志文件的最大大小(默认值: 10MB)
logging.logback.rollingpolicy.total-size-cap 日志文件被删除之前,可以容纳的最大大小 (默认值:0B)。设置1GB则磁盘存储超过 1GB 日志后就会删除旧日志文件
logging.logback.rollingpolicy.max-history 日志文件保存的最大天数(默认值:7)

自定义配置

通常我们配置 application.properties 就够了。当然也可以自定义。比如:

日志系统 自定义
Logback logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

如果可能,我们建议您在日志配置中使用 -spring 变量(例如, logback-spring.xml 而 不是 logback.xml )。如果您使用标准配置文件,spring 无法完全控制日志初始化。 最佳实战:自己要写配置,配置文件名加上 xx-spring.xml

我这里给一份我自己用的配置吧:

<configuration>

    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>

    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- INFO级别日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./logs/info/info.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 每天生成一个文件,超过10MB则切割 -->
            <fileNamePattern>./logs/info/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <!-- 保留 30 天日志 -->
            <maxHistory>30</maxHistory>
            <!-- 限制总大小,避免磁盘爆掉,可选 -->
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level --- [%thread] %logger{50} : %msg%n</pattern>
        </encoder>
    </appender>

    <!-- DEBUG级别日志 -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./logs/debug/debug.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>./logs/debug/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <maxHistory>30</maxHistory>
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level --- [%thread] %logger{50} : %msg%n</pattern>
        </encoder>
    </appender>

    <!-- ERROR级别日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./logs/error/error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>./logs/error/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <maxHistory>30</maxHistory>
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level --- [%thread] %logger{50} : %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 根日志级别 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="DEBUG_FILE"/>
        <appender-ref ref="ERROR_FILE"/>
    </root>

</configuration>

最佳实践

  1. 导入任何第三方框架,先排除它的日志包,因为Boot底层控制好了日志
  2. 修改 application.properties 配置文件,就可以调整日志的所有行为。如果不够,可 以编写日志框架自己的配置文件放在类路径下就行,比如 logback-spring.xml , log4 j2-spring.xml
  3. 如需对接专业日志系统,也只需要把 logback 记录的日志灌倒 kafka之类的中间件,这和 SpringBoot没关系,都是日志框架自己的配置,修改配置文件即可
  4. 业务中使用slf4j-api记录日志。不要再 sout 了