本文目录导读:

我来为你详细介绍SLF4J的整合使用方法,包含多个实际案例。
SLF4J + Logback 整合(最常用方案)
Maven依赖配置
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- Logback 实现 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.11</version>
</dependency>
logback.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 定义日志文件路径 -->
<property name="LOG_PATH" value="./logs"/>
<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" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天滚动 -->
<fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 保留30天日志 -->
<maxHistory>30</maxHistory>
<!-- 单个文件最大100MB -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 错误日志单独输出 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 根日志级别 -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
<!-- 特定包的日志级别 -->
<logger name="com.example" level="DEBUG"/>
</configuration>
使用示例
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
public void createUser(String username, String email) {
logger.info("开始创建用户: {}", username);
try {
// 业务逻辑
logger.debug("用户参数: username={}, email={}", username, email);
// 占位符替换
logger.info("用户 {} 创建成功, 邮箱: {}", username, email);
} catch (Exception e) {
logger.error("创建用户失败: {}", username, e);
throw new RuntimeException("创建用户失败", e);
}
}
}
SLF4J + Log4j2 整合
Maven依赖
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- Log4j2 桥接 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
log4j2.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="basePath">./logs</Property>
</Properties>
<Appenders>
<!-- 控制台输出 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<!-- 滚动文件 -->
<RollingFile name="RollingFile"
fileName="${basePath}/app.log"
filePattern="${basePath}/app-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
<!-- 特定包级别 -->
<Logger name="com.example" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Logger>
</Loggers>
</Configuration>
Spring Boot 整合 SLF4J
Spring Boot 自动配置(application.yml)
logging:
level:
root: INFO
com.example: DEBUG
org.springframework.web: INFO
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
file:
name: ./logs/spring-boot-app.log
max-size: 100MB
max-history: 30
Spring Boot 中的使用
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
// 或者使用 Lombok 注解
// @Slf4j
public void processOrder(String orderId) {
log.info("Processing order: {}", orderId);
try {
// 业务处理
log.debug("Order details loaded for: {}", orderId);
// 使用MDC添加上下文信息
MDC.put("orderId", orderId);
log.info("Order processed successfully");
} catch (Exception e) {
log.error("Failed to process order: {}", orderId, e);
} finally {
MDC.clear();
}
}
}
高级使用技巧
1 使用MDC进行日志追踪
import org.slf4j.MDC;
public class RequestFilter {
private static final Logger logger = LoggerFactory.getLogger(RequestFilter.class);
public void handleRequest(String requestId, String userId) {
// 设置MDC上下文
MDC.put("requestId", requestId);
MDC.put("userId", userId);
try {
logger.info("开始处理请求");
// 业务逻辑...
// 建议在使用MDC的代码块中使用try-with-resources
} finally {
// 清理MDC
MDC.clear();
}
}
}
2 配置MDC输出
<!-- logback.xml 配置MDC输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%X{requestId}] [%X{userId}] - %msg%n</pattern>
</encoder>
</appender>
3 条件日志
public class ConditionalLogging {
private static final Logger logger = LoggerFactory.getLogger(ConditionalLogging.class);
public void processLargeData(List<String> data) {
// 使用 isXxxEnabled 避免不必要的字符串拼接
if (logger.isDebugEnabled()) {
logger.debug("Processing {} records: {}", data.size(), data);
}
// SLF4J 2.0+ 支持 lambda 表达式
logger.atDebug()
.setMessage("Processing {} records")
.addArgument(data::size)
.log();
}
}
4 性能优化示例
public class PerformanceLogging {
private static final Logger logger = LoggerFactory.getLogger(PerformanceLogging.class);
public void optimizedLogging() {
// 不推荐 - 即使日志级别不匹配也会执行字符串拼接
// logger.debug("User: " + user + " with role: " + role);
// 推荐 - 使用占位符
logger.debug("User: {} with role: {}", user, role);
// 或使用条件判断
if (logger.isDebugEnabled()) {
logger.debug("Complex object: {}", expensiveToStringMethod());
}
// SLF4J 2.0 推荐的lambda方式
logger.atDebug()
.setMessage("Complex object: {}")
.addArgument(() -> expensiveToStringMethod())
.log();
}
}
常见问题解决
1 排除冲突依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
2 桥接旧版日志框架
<!-- 桥接commons-logging到SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>2.0.9</version>
</dependency>
<!-- 桥接java.util.logging到SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>2.0.9</version>
</dependency>
<!-- 桥接log4j 1.x到SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>2.0.9</version>
</dependency>
这些示例涵盖了SLF4J的主要使用场景和最佳实践,选择哪种方案取决于你的项目需求,对于Spring Boot项目,推荐使用SLF4J + Logback的默认配置。