一、为什么选择 logback?
logback 是 slf4j 的实现,提供了以下优势:
- 高性能:logback 的性能优于 log4j,并且在处理日志时效率很高。
- 日志输出灵活:支持多种输出方式,包括控制台、文件、数据库等。
- 日志滚动机制:支持基于时间、大小的日志文件滚动,避免单个日志文件过大。
- 动态配置:可以在不重启应用的情况下修改日志配置。
- 与 spring boot 集成:spring boot 默认使用 logback,且易于集成。
二、环境准备
假设我们正在开发一个电商应用程序。我们需要为项目中的各个模块(如购物车模块、订单模块等)记录日志。下面是我们需要用到的技术栈:
- spring boot 3.x
- logback(已与 spring boot 默认集成)
- slf4j(作为日志接口)
三、配置 logback
1、配置文件 logback.xml
在 spring boot 项目的 resources 目录下,我们通常会添加一个名为 logback.xml 的文件,用于配置日志的输出格式、级别、文件位置等。
<?xml version="1.0" encoding="utf-8"?>
<configuration scan="true" scanperiod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/donglin-cart" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{yyyy-mm-dd hh:mm:ss.sss} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.consoleappender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统操作日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.rollingfileappender">
<file>${log.path}/info.log</file>
<!-- 日志文件滚动策略:基于时间滚动 -->
<rollingpolicy class="ch.qos.logback.core.rolling.timebasedrollingpolicy">
<filenamepattern>${log.path}/info.%d{yyyy-mm-dd}.log</filenamepattern>
<maxhistory>30</maxhistory> <!-- 保留最多30天的日志 -->
</rollingpolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.levelfilter">
<level>info</level>
<onmatch>accept</onmatch>
<onmismatch>deny</onmismatch>
</filter>
</appender>
<!-- 错误日志输出 -->
<appender name="file_error" class="ch.qos.logback.core.rolling.rollingfileappender">
<file>${log.path}/error.log</file>
<rollingpolicy class="ch.qos.logback.core.rolling.timebasedrollingpolicy">
<filenamepattern>${log.path}/error.%d{yyyy-mm-dd}.log</filenamepattern>
<maxhistory>30</maxhistory>
</rollingpolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.levelfilter">
<level>error</level>
<onmatch>accept</onmatch>
<onmismatch>deny</onmismatch>
</filter>
</appender>
<!-- 设置日志级别 com.donglin.ai这个目录下的都会被记录-->
<logger name="com.donglin.ai" level="info" />
<logger name="org.springframework" level="warn" />
<!-- 根日志配置 -->
<root level="info">
<appender-ref ref="console" />
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
</configuration>
配置解析:
- log.path:定义了日志文件的存放路径。在本例中,日志文件将保存在
logs/donglin-cart目录下。 - log.pattern:定义了日志输出的格式,包含了时间戳、线程名、日志级别、日志消息等。
- console appender:配置了控制台输出,将日志输出到开发者的控制台。
- rollingfileappender:配置了日志文件输出,并且使用时间滚动策略。每天一个新文件,并且最多保留 30 天的日志。
- levelfilter:用于过滤日志级别。
file_info只输出info及以上的日志,file_error只输出error级别的日志。 - logger:为特定的包设置了日志级别。在本例中,
com.donglin.ai包的日志级别为info,org.springframework包的日志级别为warn。
四、实战案例:购物车模块日志记录
在电商项目中,我们要在购物车模块中记录操作日志。比如,当用户将商品添加到购物车时,我们希望记录下商品信息、数量以及操作时间等。
1、cartserviceimpl.java
package com.donglin.java.ai.langchain4j.service.impl;
import com.donglin.java.ai.langchain4j.service.cartservice;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.stereotype.service;
@service
public class cartserviceimpl implements cartservice {
private static final logger logger = loggerfactory.getlogger(cartserviceimpl.class);
public void addtocart(long userid, long productid, integer quantity) {
// 记录普通信息日志
logger.info("用户 {} 添加商品 {} 到购物车,数量: {}", userid, productid, quantity);
// 模拟业务逻辑
if (quantity <= 0) {
// 记录错误日志
logger.error("添加商品失败,商品数量无效: {}", quantity);
throw new illegalargumentexception("商品数量无效");
}
// 记录调试日志
logger.debug("正在将商品 {} 添加到用户 {} 的购物车中...", productid, userid);
// 成功后记录信息日志
logger.info("商品 {} 成功添加到用户 {} 的购物车中", productid, userid);
}
}
2、cartcontroller.java
package com.donglin.java.ai.langchain4j.controller;
import com.donglin.java.ai.langchain4j.service.cartservice;
import io.swagger.v3.oas.annotations.operation;
import io.swagger.v3.oas.annotations.parameter;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.*;
@restcontroller
@requestmapping("/cart")
public class cartcontroller {
@autowired
private cartservice cartservice;
@operation(summary = "将商品添加到购物车", description = "根据用户id、商品id和数量将商品添加到购物车")
@postmapping("/add")
public string addtocart(
@parameter(name = "userid", description = "用户id", required = true) @requestparam long userid,
@parameter(name = "productid", description = "商品id", required = true) @requestparam long productid,
@parameter(name = "quantity", description = "商品数量", required = true) @requestparam integer quantity) {
try {
cartservice.addtocart(userid, productid, quantity);
return "商品已成功添加到购物车";
} catch (exception e) {
// 错误日志
return "添加商品到购物车失败";
}
}
}
3、日志输出
在控制台和日志文件中,你将看到如下日志输出:
控制台日志:
2025-10-11 14:23:44.526 [http-nio-8081-exec-3] info c.d.j.a.l.s.impl.cartserviceimpl - 用户 1 添加商品 2 到购物车,数量: 6 2025-10-11 14:23:44.527 [http-nio-8081-exec-3] info c.d.j.a.l.s.impl.cartserviceimpl - 商品 2 成功添加到用户 1 的购物车中 2025-10-11 14:23:45.089 [http-nio-8081-exec-4] info c.d.j.a.l.s.impl.cartserviceimpl - 用户 1 添加商品 2 到购物车,数量: 6 2025-10-11 14:23:45.089 [http-nio-8081-exec-4] info c.d.j.a.l.s.impl.cartserviceimpl - 商品 2 成功添加到用户 1 的购物车中 2025-10-11 14:23:45.521 [http-nio-8081-exec-5] info c.d.j.a.l.s.impl.cartserviceimpl - 用户 1 添加商品 2 到购物车,数量: 6 2025-10-11 14:23:45.521 [http-nio-8081-exec-5] info c.d.j.a.l.s.impl.cartserviceimpl - 商品 2 成功添加到用户 1 的购物车中 2025-10-11 14:23:48.322 [http-nio-8081-exec-6] info c.d.j.a.l.s.impl.cartserviceimpl - 用户 1 添加商品 2 到购物车,数量: 0
错误日志文件(error.log):
2025-10-11 14:23:49.304 [http-nio-8081-exec-7] error c.d.j.a.l.s.impl.cartserviceimpl - 添加商品失败,商品数量无效: 0

五、文件生成的时间点
在使用 timebasedrollingpolicy 配置时,日志文件的切割是基于时间的,通常是按照每天的零点来生成新的日志文件。所以,当你设置了:
<filenamepattern>${log.path}/info.%d{yyyy-mm-dd}.log</filenamepattern>
这意味着 日志文件每天都会滚动并生成一个新文件,但是:
- 当天的日志文件会一直记录到第二天的零点才会被切割为新的文件。
- 第二天零点时,现有的
info.log文件会被重命名为info.yyyy-mm-dd.log(按日期命名),并创建一个新的info.log用于继续记录新的日志。
因此,今天生成的日志文件不会立即滚动到第二天的新文件,需要等到第二天零点才会生成新的日志文件。
1、验证
修改系统时间

成功生成

六、总结
- 配置了日志的输出路径、格式和滚动策略。
- 结合实际业务场景,在
cartservice中记录了普通操作日志、调试日志和错误日志。 - 通过 logback 配置文件控制日志的输出位置(控制台和文件)以及不同级别的日志过滤。
以上就是使用logback在springboot项目中实现日志记录功能的详细内容,更多关于springboot logback日志记录的资料请关注代码网其它相关文章!
发表评论