当前位置: 首页 > news >正文

SpringBoot 日志管理

目录

一、简介

二、默认日志格式

三、修改日志显示格式

四、日志显示级别

4.1 基本原则

4.2 修改默认显示级别

五、日志分组

六、输出到文件

七、日志归档与切割

7.1 说明

7.2 规则

八、自定义日志配置

九、切换日志组合


一、简介

先说明:项目中不要写System.out.println(),应该用日志记录信息!

而关于日志的演变也是非常久远的。JDK1.4 开始,通过 java.util.logging 提供日志功能。虽然是官方自带的log lib,JUL的使用确不广泛。原因其实简单:就是那个时候做的真的很烂,也非常不好用。所以后面逐渐涌现出来像Log4j、Logback等优秀的日志框架。

今天,我们不会去深度探讨这其中的关系,重在讲解Springboot应用中的主要用法。如果对这方面感兴趣,可以参考这篇文章https://pdai.tech/md/develop/package/dev-package-x-log.html

好,正篇开始!

Spring使用commons-logging作为内部日志,但底层日志实现是开放的。可对接其他日志框架。

在Spring5以后,common-logging被spring直接自己写了。

Spring Boot默认使用Logback作为其日志框架。

Spring boot的每个starter场景,都会引入一个核心场景spring-boot-starter

这个spring-boot-starter下就引入了这个spring-boot-starter-logging这个日志依赖。

我们再进去看一下,就看到了logback-classic依赖。

而日志是利用监听器机制配置好的,和其他的自动装配不太一样,因为日志需要一启动就要运行,具体的我们后面再细说。

另外,日志是所有配置都可以通过修改配置文件实现。以logging开头的所有配置。

二、默认日志格式

启动springboot项目,我们可以看到控制台打印的日志信息,如下所示:

2025-06-12 17:34:27.683  INFO 35252 --- [           main] com.cisdi.info.Application               : Starting Application on pps with PID 35252 (E:\project\workspace\work\zk_new\heat_optimize_app\target\classes started by hssym in E:\project\workspace\work\zk_new\heat_optimize_app)
2025-06-12 17:34:27.684  INFO 35252 --- [           main] com.cisdi.info.Application               : The following profiles are active: test
2025-06-12 17:34:28.673  INFO 35252 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2025-06-12 17:34:28.675  INFO 35252 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-06-12 17:34:28.734  INFO 35252 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 45ms. Found 0 Redis repository interfaces.
2025-06-12 17:34:29.023  WARN 35252 --- [           main] o.m.s.mapper.ClassPathMapperScanner      : No MyBatis mapper was found in '[com.cisdi.info.mapper]' package. Please check your configuration.
2025-06-12 17:34:30.309  INFO 35252 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.datasource.dynamic-com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties' of type [com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

默认的日志格式从左到右由这几部分组成:

  • 日期时间: 精确到毫秒级别  2025-06-12 17:34:27.683
  • 日志级别: TRACE、DEBUG、INFO、WARN、ERROR等  INFO
  • 进程ID  35252
  • ---: 消息分隔符
  • 线程名: 用[]包含起来   [           main]
  • Logger名: 通常是产生日志的类名  com.cisdi.info.Application
  • 消息: 日志记录的内容 Starting Application on pps with PID 35252 

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

三、修改日志显示格式

在springboot的底层,spring-boot包下就定义好了日志的配置信息

这里就不带大家细看了,感兴趣的可以自行研究。

如果要修改日志的显示格式,主要用到 logging.pattern 开头的配置,直接在配置文件修改即可。

例如:logging.pattern.dateformat=yyyy年MM月dd日 HH:mm:ss.SSS

四、日志显示级别

4.1 基本原则

日志级别从低到高分别是

ALL TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF

系统只会打印指定级别及以上级别的日志

举例说明

springboot默认的日志显示级别是INFO

换句话说:默认是可以打印出来INFO、WARN、ERROR级别的日志信息。

4.2 修改默认显示级别

Springboot可以更改默认日志级别,甚至X能精确到某个包、某个类。

配置文件中配置logging.level.<logger-name>=<level>指定日志级别。

level可取值范围:TRACE DEBUG  INFO WARN ERROR

更改Springboot下所有日志的级别

logging.level.root=debug

更改某个包的日志级别

logging.level.com.hssy.info.controller=debug

更改某个类的日志级别

logging.level.com.cisdi.info.controller.TestController=debug


五、日志分组

如果我们想批量调整某些包下或者某些类的日志级别,当然可以像前面讲解的那样些。

随着修改的日志规则越多,这种方式显然比较麻烦。那么我们就可以对日志进行分组。

logging.group.<自定义组名>

上述就可以替换成如下所示

这么做的好处是可以对日志进行分组批量管理。对日志规则复杂一点的,分组的优势是很明显的。

Springboot底层也提供了几个默认的分组:

NameLoggers
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

六、输出到文件

Spring默认将日志输出到控制台,但是一般情况下,应用上线到生产环境后,我们希望将它输出到文件中。

这样做的好处是一旦应用出现什么问题,我们也可以通过日志文件进行定位排查。相当于对日志进行了持久化操作。

log.file.name=(路径)名称

  • 只写名称,如果不指定路径,那么日志文件默认放在和项目下。
  • 路径 + 名称, 那么日志文件就存放在指定的路径下。

(了解)logging.file.path=路径

通过这种方式,只能写路径,不能写名称。系统会自动生成一个叫spring.log的日志文件。

如果这两种方式你都写了,那么只有logging.file.name会生效。

因此,建议用logging.file.name的方式!

七、日志归档与切割

7.1 说明

如果将日志都放在同一个文件下,那么随着时间的推移,这个文件肯定会越来越大,最后面临的问题是这个日志文件根本无法查阅,甚至还会降低系统的性能。

因此,我们建议是按日期对日志进行归档。

比如每天的日志都放在一个文件中,这样项目的日志文件就会被分散到各天的日志文件里。

但是这样还有一个问题,假如某天并发量很高,又或者频繁出现故障,打印超多的日志信息。那么依然会面临大文件的问题。

所以,这里有提出了日志切割的想法。

我们可以将同一天的日志切割成不同的文件,又进行分别存储。比如文件超过10MB,就切割成另外一个文件进行存储。

7.2 规则

如果使用的logback(springboot默认整合),可以通过 application.properties文件指定日志滚动规则。

如果是其他日志系统,需要自行配置(添加log4j2.xml 或 log4j2-spring.xml)。

支持的滚动规则如下:

配置项描述
logging.logback.rollingpolicy.file-name-pattern

日志存档的文件名格式

默认值:${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz

logging.logback.rollingpolicy.clean-history-on-start

应用启动时是否清除以前存档

默认值:false

logging.logback.rollingpolicy.max-file-size

存档前,每个日志文件的最大大小

默认值:10MB

logging.logback.rollingpolicy.max-history

日志文件保存的最大天数

默认值:7

logging.logback.rollingpolicy.total-size-cap

日志文件被删除之前,可以容纳的最大大小

默认值:0B

设置1GB则磁盘存储超过1GB日志后就会删除旧日志文件

注意

如果你发现,你的springboot配置文件没有这些配置项,请检查一下springboot的版本,我当前的版本是3.3.4版本。

像springboot 2.x的很多版本都没有这些配置,具体我也不清楚是从哪个版本出现的,建议参考我这个版本。

当然没有也不要慌,还有其他的配置项可以使用。如下所示:

默认值和配置名称几乎都一样,看一眼就清楚了。

只是不清楚为什么在SpringBoot3.3.4中过时了。不过这个不用管,用Spring2.x,只要还能用,那用就行了。

八、自定义日志配置

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

日志系统自定义
Logbacklogback-spring.xml、logback-spring.groovy、logback.xmll、logback.groovy
Log4j2log4j2-spring.xml、log4j2.xml

如果可能,建议在日志配置中使用-spring命名(例如:logback-spring.xml 而不是 logback.xml)。如果不带-spring,那么spring无法完全控制日志的初始化。

这边给一个logback-spring.xml 案例,把它放在resources目录下,感兴趣的可以自行研究。

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds"><!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --><!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true --><!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 --><!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --><contextName>logback</contextName><!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --><property name="log.path" value="D:/guli_log/edu" /><!-- 彩色日志 --><!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 --><!-- magenta:洋红 --><!-- boldMagenta:粗红--><!-- cyan:青色 --><!-- white:白色 --><!-- magenta:洋红 --><property name="CONSOLE_LOG_PATTERN"value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/><!--输出到控制台--><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--><!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 --><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter><encoder><Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!-- 设置字符集 --><charset>UTF-8</charset></encoder></appender><!--输出到文件--><!-- 时间滚动输出 level为 INFO 日志 --><appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_info.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 每天日志归档路径以及格式 --><fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录info级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 WARN 日志 --><appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_warn.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录warn级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>warn</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 ERROR 日志 --><appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_error.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录ERROR级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!--<logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。<logger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。name:用来指定受此logger约束的某一个包或者具体的某一个类。level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,如果未设置此属性,那么当前logger将会继承上级的级别。--><!--使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:--><!--开发环境:打印控制台--><springProfile name="dev"><!--可以输出项目中的debug日志,包括mybatis的sql日志--><logger name="com.guli" level="INFO" /><!--root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG可以包含零个或多个appender元素。--><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="INFO_FILE" /><appender-ref ref="WARN_FILE" /><appender-ref ref="ERROR_FILE" /></root></springProfile><!--生产环境:输出到文件--><springProfile name="pro"><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="DEBUG_FILE" /><appender-ref ref="INFO_FILE" /><appender-ref ref="ERROR_FILE" /><appender-ref ref="WARN_FILE" /></root></springProfile></configuration>

需要说明一点的是,通过application.yaml配置和xml文件两种方式,建议不要混用,如果两种都用的话,可能只会xml文件生效。

九、切换日志组合

如果我们不希望用springboot默认的logback日志框架,那么我们也可以改用其他的日志框架。

怎么做呢?

首先,在springboot的官方starter中,就提供了log4j2的依赖,叫spring-boot-starter-log4j2。

只不过默认的是spring-boot-starter-logging。

要切换也很简单。

在自己的pom.xml文件中,利用maven的就近原则,导入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>

这还没完,需要排除默认的 spring-boot-starter-logging 依赖。然后再引入spring-boot-starter-log4j2。

所以就应该是这样:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</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>

使用log4j2后,配置文件的方式设置日志参数依旧一样,可以不用动。但如果是自定义的日志xml文件,则不一样了,需要替换掉。这里也给出一个log4j2-spring.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!-- status="WARN"是Log4j2框架的日志级别,当框架启动有问题,会根据此配置来打印日志-->
<Configuration status="WARN" monitorInterval="30"><!-- 定义变量 --><Properties><Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property><Property name="LOG_DIR">logs</Property><Property name="LOG_FILE_NAME">app.log</Property></Properties><!-- 定义输出器(Appenders) --><Appenders><!-- 控制台输出 --><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="${LOG_PATTERN}"/></Console><!-- 滚动文件输出 --><RollingFile name="RollingFile" fileName="${LOG_DIR}/${LOG_FILE_NAME}"filePattern="${LOG_DIR}/app-%d{yyyy-MM-dd}-%i.log.gz"><PatternLayout pattern="${LOG_PATTERN}"/><Policies><!-- 按时间滚动(每天) --><TimeBasedTriggeringPolicy interval="1" modulate="true"/><!-- 按文件大小滚动(最大 100MB) --><SizeBasedTriggeringPolicy size="100 MB"/></Policies><!-- 最多保留 30 天或 10 个文件 --><DefaultRolloverStrategy max="10"/></RollingFile><!-- 异步日志(提升性能) --><Async name="AsyncAppender" bufferSize="1024"><AppenderRef ref="RollingFile"/></Async></Appenders><!-- 定义日志记录器(Loggers) --><Loggers><!-- Spring 框架日志(INFO 级别) --><Logger name="org.springframework" level="INFO" additivity="false"><AppenderRef ref="Console"/></Logger><!-- MyBatis SQL 日志(DEBUG 级别) --><Logger name="com.example.mapper" level="DEBUG" additivity="false"><AppenderRef ref="Console"/><AppenderRef ref="AsyncAppender"/></Logger><!-- 根日志记录器(全局默认),level="INFO"是应用程序的日志级别 --><Root level="INFO"><AppenderRef ref="Console"/><AppenderRef ref="AsyncAppender"/></Root></Loggers>
</Configuration>

相关文章:

  • 什么是探索式测试,应该怎么做?
  • 视觉语言模型的“视而不见“
  • 初认Flask框架
  • 基于深度学习的智能语音合成系统:技术与实践
  • pmset - 控制 macOS 系统电源、睡眠、唤醒与节能
  • 隧道代理IP的使用与技术优势分析
  • 学习笔记:Redis入门
  • Trae国内版Builder模式VS Chat模式
  • 表格对比工具推荐,快速比对Excel文件
  • 开疆智能ModbusTCP转Devicenet网关连接西门子200Smart与费托斯阀岛案例
  • 数据库中的Schema是什么?不同数据库中Schema的含义
  • Charles 抓包工具使用教程
  • OpenLayers 图层叠加控制
  • 芯片测试之VIL/VIH(输入电平)Test全解析:从原理到实战
  • 服务器上安装配置vsftpd
  • Webpack:现代前端构建工具的核心解析
  • 深入理解 @JsonGetter:精准掌控前端返回数据格式!
  • 26考研 | 王道 | 计算机组成原理 | 七、输入输出系统
  • PHP设计模式实战:领域驱动设计与六边形架构
  • life long learning
  • 电商网站的人员团队建设/广告营销案例分析
  • 便宜做网站的公司靠谱吗/东莞今天最新消息新闻
  • 快速提升网站权重/深圳seo优化排名
  • 买完域名后怎么做网站/云南百度公司
  • 武汉seo网站排名/快手seo软件下载
  • 今日头条开放api接口/seo黑帽培训骗局