在springboot中配置日志文件非常简单,使用也很简单。稍微复杂的可能就是相关的logback.xml配置文件,下面我们对常见的日志配置文件进行解读
xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<configuration debug="false" scan="true" scanPeriod="3600 seconds">
<!-- 文件相对保存路径设置可分以下三种:
1. value="logs" -- 表示保存到程序运行目录下的logs目录
2. value="./" -- 表示保存到程序运行目录
3. value="../logs" -- 表示保存到程序运行目录的父目录
-->
<property name="LOG_HOME" value="logs"/>
<property name="ROOT_LOG_LEVEL" value="DEBUG"/>
<property name="FILE_LOG_LEVEL" value="DEBUG"/>
<property name="CONSOLE_LOG_LEVEL" value="DEBUG"/>
<property name="FILE_NAME" value="springbootlearn"/>
<!-- 定义日志文件大小和周期 -->
<property name="log.maxSize" value="100MB"/>
<property name="log.maxHistory" value="30"/>
<!-- 日志格式配置,下面提供了两种方案 -->
<!-- <property name="CONSOLE_LOG_PATTERN"-->
<!-- value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- %magenta([%X{traceId}]) [%thread] %green(%class{50}):%cyan(%method) : %msg%n">-->
<!-- </property>-->
<property name="FILE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%X{traceId}] [%thread] %class{50}:%method : %msg%n">
</property>
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{50} - %msg%n"/>
<!-- appender:定义了日志输出目的地
1. ch.qos.logback.core.ConsoleAppender定义的目的地为控制台,不存储进日志文件
2. ch.qos.logback.core.rolling.RollingFileAppender定义的目的地为日志文件,不在控制台显示
-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!--定义了一个过滤器,在LEVEL之下的日志输出不会被打印出来-->
<!--这里定义了DEBUG,也就是控制台不会输出比DEBUG级别小的日志-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${CONSOLE_LOG_LEVEL}</level>
</filter>
<!--定义控制台输出格式-->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志名称 -->
<file>${LOG_HOME}/${FILE_NAME}.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${FILE_LOG_LEVEL}</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_HOME}/${FILE_NAME}.%d{yyyy-MM-dd}.%i.log.zip
</fileNamePattern>
<maxHistory>${log.maxHistory}</maxHistory>
<maxFileSize>${log.maxSize}</maxFileSize>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 可以为不同包或类定义日志各自的日志输出级别 -->
<logger name="org.springframework.web" level="DEBUG"/>
<logger name="com.xxc.learnboot" level="DEBUG"/>
<!--root是默认的logger,默认级别是debug-->
<root level="${ROOT_LOG_LEVEL}">
<!-- 此appender向控制台输出 -->
<appender-ref ref="console"/>
<!-- 此appender生成日志文件 -->
<appender-ref ref="file"/>
</root>
</configuration>
解读如下:
好的,我们来详细分析一下你提供的这个 logback-spring.xml
配置文件。这是一个相当标准和功能完善的 Logback 配置。
整体概览
这个配置文件定义了日志的输出行为,包括:
- 自动重载配置:当配置文件发生变化时,Logback 可以自动重新加载。
- 日志存储路径和级别:通过属性定义了日志文件的存放位置和各种默认日志级别。
- 日志文件命名和大小限制:定义了日志文件的基础名称、最大大小以及历史文件保留数量。
- 两种日志输出格式:分别为控制台输出和文件输出定义了不同的日志格式(尽管控制台有一个被注释掉了)。
- 两种日志输出目的地 (Appender) :
- 控制台 (console):将日志打印到标准输出。
- 文件 (file):将日志写入到文件中,并配置了日志滚动(按大小和时间)和压缩。
- 特定包的日志级别控制 :为 Spring MVC (
org.springframework.web
) 和你自己的应用包 (com.xxc.learnboot
) 设置了特定的日志级别。 - 根 Logger 配置:定义了全局的默认日志级别,并将控制台和文件输出都关联到了根 Logger。
逐段分析
-
<configuration>
元素xml<configuration debug="false" scan="true" scanPeriod="3600 seconds">
debug="false"
: 这意味着 Logback 内部的调试信息不会被打印。在生产环境中通常设置为false
。如果遇到 Logback 配置不生效的问题,可以临时设置为true
来查看 Logback 的加载和运行状态。scan="true"
: 启用配置文件的自动扫描和重载。如果logback-spring.xml
文件在运行时被修改,Logback 会检测到变化并重新加载配置,无需重启应用。这在开发和需要动态调整日志级别的场景下很有用。scanPeriod="3600 seconds"
: 设置扫描配置文件变更的时间间隔为 3600 秒(1 小时)。当scan="true"
时此属性生效。
-
<property>
元素 - 全局属性定义xml<property name="LOG_HOME" value="logs"/> <property name="ROOT_LOG_LEVEL" value="DEBUG"/> <property name="FILE_LOG_LEVEL" value="DEBUG"/> <property name="CONSOLE_LOG_LEVEL" value="DEBUG"/> <property name="FILE_NAME" value="springbootlearn"/> <property name="log.maxSize" value="100MB"/> <property name="log.maxHistory" value="30"/>
LOG_HOME
: 定义日志文件存储的根目录为程序运行目录下的logs
文件夹。ROOT_LOG_LEVEL
: 设置根 Logger 的默认级别为DEBUG
。这意味着,除非特定 Logger 有更精确的设置,否则所有日志事件都将以DEBUG
级别进行处理。FILE_LOG_LEVEL
: 为文件 Appender 设置的阈值过滤器级别为DEBUG
。CONSOLE_LOG_LEVEL
: 为控制台 Appender 设置的阈值过滤器级别为DEBUG
。FILE_NAME
: 日志文件的基础名称为springbootlearn
。最终文件名会是springbootlearn.log
。log.maxSize
: 定义了单个日志文件的最大尺寸为100MB
。当文件达到此大小时,会触发滚动。log.maxHistory
: 定义了日志文件保留的最大历史数量(或天数,取决于滚动策略)为30
。
-
<property>
元素 - 日志格式定义xml<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%X{traceId}] [%thread] %class{50}:%method : %msg%n"> </property> <property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{50} - %msg%n"/>
- 注释掉的
CONSOLE_LOG_PATTERN
:%d{yyyy-MM-dd HH:mm:ss.SSS}
: 日期和时间。%highlight(%-5level)
: 高亮显示日志级别,左对齐,宽度为5。---
: 分隔符。%magenta([%X{traceId}])
: 紫色显示 MDC (Mapped Diagnostic Context) 中的traceId
(如果存在)。这对于分布式追踪非常有用。[%thread]
: 当前线程名。%green(%class{50})
: 绿色显示类名,最大长度50,通常会自动缩写包名。%cyan(%method)
: 青色显示方法名。注意:输出方法名%method
会有性能损耗,因为它需要生成调用者数据。在生产环境中应谨慎使用。%msg%n
: 日志消息和换行符。
- 生效的
FILE_LOG_PATTERN
:%d{yyyy-MM-dd HH:mm:ss.SSS}
: 日期和时间。%-5level
: 日志级别,左对齐,宽度为5。---
: 分隔符。[%X{traceId}]
: MDC 中的traceId
。[%thread]
: 当前线程名。%class{50}
: 类名,最大长度50。%method
: 方法名。同样,注意性能影响。%msg%n
: 日志消息和换行符。
- 生效的
CONSOLE_LOG_PATTERN
:%d{yyyy-MM-dd HH:mm:ss.SSS}
: 日期和时间。%-5level
: 日志级别,左对齐,宽度为5。%logger{50}
: Logger 名称(通常是类名),最大长度50。与%class
类似,但%logger
是 Logger 的名字,而%class
是事件发生处的类名。在简单情况下它们可能相同。- %msg%n
: 分隔符、日志消息和换行符。
这个控制台格式相对简洁。
- 注释掉的
-
<appender name="console">
- 控制台输出器xml<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>${CONSOLE_LOG_LEVEL}</level> </filter> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender>
class="ch.qos.logback.core.ConsoleAppender"
: 指定这是一个向控制台输出日志的 Appender。<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
: 添加了一个阈值过滤器。<level>${CONSOLE_LOG_LEVEL}</level>
: 当前设置为DEBUG
。这意味着只有级别为DEBUG
或更高级别 (INFO, WARN, ERROR) 的日志事件才会通过此过滤器,从而被这个 Appender 处理(即打印到控制台)。TRACE 级别的日志将不会在控制台显示。
<encoder>
: 配置日志的格式化方式。<pattern>${CONSOLE_LOG_PATTERN}</pattern>
: 使用前面定义的控制台日志格式。<charset>UTF-8</charset>
: 设置字符编码为 UTF-8,以避免乱码。
-
<appender name="file">
- 文件输出器xml<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${FILE_NAME}.log</file> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>${FILE_LOG_LEVEL}</level> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern> ${LOG_HOME}/${FILE_NAME}.%d{yyyy-MM-dd}.%i.log.zip </fileNamePattern> <maxHistory>${log.maxHistory}</maxHistory> <maxFileSize>${log.maxSize}</maxFileSize> </rollingPolicy> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender>
class="ch.qos.logback.core.rolling.RollingFileAppender"
: 指定这是一个会将日志写入文件,并支持日志滚动的 Appender。<file>${LOG_HOME}/${FILE_NAME}.log</file>
: 当前活动日志文件的路径和名称,例如logs/springbootlearn.log
。<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
: 同样使用了阈值过滤器。<level>${FILE_LOG_LEVEL}</level>
: 当前设置为DEBUG
。这意味着只有级别为DEBUG
或更高级别的日志才会写入文件。
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
: 配置日志滚动策略,这里是基于时间和大小的滚动。<fileNamePattern>${LOG_HOME}/${FILE_NAME}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
: 定义了归档日志文件的命名模式。%d{yyyy-MM-dd}
: 按日期滚动,每天一个新文件。%i
: 当天内如果日志文件大小超过maxFileSize
,则通过递增索引%i
(0, 1, 2...) 来创建新的分割文件。.zip
: 归档的日志文件会被压缩成 zip 格式,以节省磁盘空间。
<maxHistory>${log.maxHistory}</maxHistory>
: 保留最近30
天(或30个归档文件,取决于具体策略如何解释)的日志文件。<maxFileSize>${log.maxSize}</maxFileSize>
: 单个日志文件的最大大小为100MB
。超过此大小会触发滚动(如果仍在同一天,则索引%i
增加)。
<encoder>
: 文件日志的编码器。<pattern>${FILE_LOG_PATTERN}</pattern>
: 使用前面定义的文件日志格式。<charset>UTF-8</charset>
: 字符编码。
-
<logger>
元素 - 特定包的日志级别xml<logger name="org.springframework.web" level="DEBUG"/> <logger name="com.xxc.learnboot" level="DEBUG"/>
<logger name="org.springframework.web" level="DEBUG"/>
: 将org.springframework.web
包(及其子包)下的所有 Logger 的级别设置为DEBUG
。这将输出 Spring MVC 处理请求的详细信息。<logger name="com.xxc.learnboot" level="DEBUG"/>
: 将com.xxc.learnboot
包(及其子包)下的所有 Logger 的级别设置为DEBUG
。这是你应用程序主包的日志级别设置。- 重要 :这些
<logger>
元素没有指定additivity="false"
。这意味着,除了它们自己处理日志事件外,这些事件还会向上传播到父 Logger(最终到 root Logger)。由于 root Logger 也配置了 console 和 file Appender,这意味着org.springframework.web
和com.xxc.learnboot
的 DEBUG 及以上级别的日志,可能会在控制台和文件中各输出一次 (一次由这个logger自己的appender(如果配置了),一次由root logger的appender)。不过,因为这些特定的 logger 元素没有自己的appender-ref
,所以它们实际上是依赖 root logger 的 appender 来输出。这里的设置主要是为了覆盖 root logger 的级别。
-
<root>
元素 - 根 Loggerxml<root level="${ROOT_LOG_LEVEL}"> <appender-ref ref="console"/> <appender-ref ref="file"/> </root>
level="${ROOT_LOG_LEVEL}"
: 设置根 Logger 的级别为DEBUG
(通过属性${ROOT_LOG_LEVEL}
获取)。这是所有 Logger 的最终默认级别,除非被更具体的<logger>
元素覆盖。<appender-ref ref="console"/>
: 将名为 "console" 的 Appender 附加到根 Logger。<appender-ref ref="file"/>
: 将名为 "file" 的 Appender 附加到根 Logger。- 这意味着,默认情况下,所有级别在
DEBUG
及以上的日志事件(未被特定 logger 拦截或其 additivity 设置为 false 的)都会同时输出到控制台和日志文件。
总结与建议
- 配置清晰且功能全面:这个配置文件覆盖了日志级别、输出格式、输出目的地(控制台和文件)、日志滚动和压缩等常见需求。
- 日志级别设置 :当前大部分关键部分的日志级别(root, file, console, 以及特定包)都设置为
DEBUG
。这在开发阶段非常有用,可以获取大量信息。但在生产环境 中,通常会将默认级别调整为INFO
或WARN
,以避免产生过多的日志,影响性能和存储。DEBUG
级别可以按需为特定故障排除的包开启。 - 性能考虑 (
%method
) :文件日志格式中使用了%method
。如前所述,获取方法名会有性能开销。在生产环境的高吞吐量场景下,如果性能敏感,可以考虑移除或仅在需要详细调试时开启。 traceId
的使用 :日志格式中包含了[%X{traceId}]
。这是一个很好的实践,用于在分布式系统中追踪请求。你需要确保在代码中通过MDC.put("traceId", "your-trace-id")
来设置它,通常在请求进入时设置,在请求结束时清理。Spring Cloud Sleuth 或 Micrometer Tracing 等库可以自动处理这个。- Appender 的过滤器 (ThresholdFilter) :
- 你为
console
和file
Appender 都设置了ThresholdFilter
。这个过滤器的作用是只允许等于或高于指定级别的日志通过。 - 例如,如果
CONSOLE_LOG_LEVEL
是DEBUG
,那么TRACE
日志即使被某个 Logger 允许(比如 Logger 的级别是 TRACE),也不会被console
Appender 打印。 - Logger 的级别决定一个日志事件是否产生 ,Appender 的过滤器决定这个 Appender 是否处理这个已产生的事件。
- 你为
- Additivity : 对于
<logger name="org.springframework.web" level="DEBUG"/>
和<logger name="com.xxc.learnboot" level="DEBUG"/>
,由于没有设置additivity="false"
,它们的日志事件会由 root logger 的 appender (console 和 file) 处理。这是常见的做法。如果只想让特定 logger 的日志输出到特定 appender,而不是也通过 root logger 输出,则需要使用additivity="false"
并为该 logger 单独配置appender-ref
。 - 文件滚动策略 :
SizeAndTimeBasedRollingPolicy
是一个很好的选择,既能按天归档,也能在当天日志量过大时进行分割,并且支持压缩。 scan
和scanPeriod
:设置为1小时扫描一次,对于生产环境来说是一个合理的折衷。过于频繁的扫描也会有轻微的性能影响。
总的来说,这是一个结构良好、功能强大的 Logback 配置文件,特别适合 Spring Boot 应用。你只需要根据部署环境(开发、测试、生产)适当调整日志级别相关的属性即可。
忽略特定包的日志输出
以下面这条日志为例
powershell
2025-05-23 21:03:20.355 DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Before shutdown stats (total=10/10, idle=10/10, active=0, waiting=0)
com.zaxxer.hikari包的作用
com.zaxxer.hikari
这个包名通常指向 HikariCP。
HikariCP 是一个非常高性能的 JDBC (Java Database Connectivity) 连接池库。
用途和重要性:
- 数据库连接管理:在 Java 应用程序中,与数据库进行交互需要建立数据库连接。直接为每个数据库操作都创建和关闭连接是非常耗费资源和时间的操作。
- 性能提升:连接池通过预先创建并维护一组数据库连接,当应用程序需要访问数据库时,可以直接从池中获取一个已建立的连接,使用完毕后再将其归还给池中,而不是销毁。这大大减少了连接创建和销毁的开销,显著提升了应用程序的性能和响应速度。
- 资源控制:连接池可以配置连接的最小数量、最大数量等参数,有效控制应用程序对数据库的并发连接数,防止因连接过多而耗尽数据库或应用服务器的资源。
- 可靠性和效率:HikariCP 以其轻量级、快速和可靠而闻名。它有很多优化,例如连接有效性检测、快速的语句缓存等,使其成为 Spring Boot 2.x 及更高版本默认的数据库连接池。
你看到的日志 2025-05-23 21:03:20.355 DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Before shutdown stats (total=10/10, idle=10/10, active=0, waiting=0)
就是 HikariCP 在关闭其连接池(名为 HikariPool-1
)之前打印的一些统计信息,比如总连接数、空闲连接数、活动连接数等。这些 DEBUG 级别的日志对于监控连接池的状态和诊断问题非常有用,但在正常运行的生产环境中,你可能不希望看到如此频繁或详细的连接池内部日志。
修改配置文件以忽略 com.zaxxer.hikari
包的日志输出
要在你提供的 logback-spring.xml
配置文件中实现对 com.zaxxer.hikari
包下的所有日志不输出打印,你需要在 <configuration>
标签内,通常是在其他 <logger>
标签附近或者 <root>
标签之前,添加一个新的 <logger>
配置。
我们将为 com.zaxxer.hikari
包设置一个专门的 logger,并将其日志级别设置为 OFF
。OFF
级别会关闭该 logger 的所有日志记录。
修改说明:
我们在 <logger name="com.xxc.learnboot" level="DEBUG"/>
之后,以及 <root ...>
之前,添加了以下行:
xml
<logger name="com.zaxxer.hikari" level="OFF"/>
name="com.zaxxer.hikari"
: 指定这个 logger 配置应用于com.zaxxer.hikari
包及其所有子包。level="OFF"
: 将这个 logger 的级别设置为OFF
。OFF
是最高级别,它会关闭所有日志消息(TRACE, DEBUG, INFO, WARN, ERROR)。因此,任何源自com.zaxxer.hikari
包的日志事件都不会被记录或打印。
重要提示:
-
Additivity :默认情况下,
<logger>
元素的additivity
属性是true
,这意味着日志事件在被这个 logger 处理后,还会向上传递给父 logger(最终到 root logger)。但是,因为我们将级别设置为OFF
,这个 logger 本身就不会产生任何日志事件传递给它的 appender(如果有的话)或父 logger 的 appender。所以,即使additivity
是true
,com.zaxxer.hikari
的日志也不会输出。如果你想更明确地表示这个 logger 不会将任何(即使是其他级别)事件传递给 root logger 的 appender,你可以添加additivity="false"
,但对于level="OFF"
来说,这通常不是必需的。xml
这样修改后,com.zaxxer.hikari
包下的所有日志(包括你示例中提到的 DEBUG 日志)都将被忽略,不会输出到控制台或日志文件中。