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

日志门面

日志实现

JCL(Jakarta Commons Logging)
SLF4j(Simple Logging for Java)
jboss-logging

Log4j

JUL(java.util.logging)
Log4j2

Logback

感兴趣的日志框架起源的与关系的可以区看这个视频: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

默认输出格式:

  • 时间和日期:毫秒级别精度

  • 日志级别: ERRORWARNINFODEBUGTRACE

  • 进程ID

  • --- :消息分割符

  • 线程名:使用[] 包含

  • Logger名:通常是产生日志的类名

  • 消息:日志记录的内容

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

默认值:参照: spring-bootadditional-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 了