曾经,我调试代码的唯一方式是System.out.println(">>> here 1 <<<")。直到线上出了问题,我面对着一台没有控制台的服务器束手无策。师傅说:“你得学会打日志。” 从此,我进入了SLF4J + Logback的世界。1. 为什么不用System.out.println?
- 无法控制输出级别: 调试完还要手动删除或屏蔽,麻烦且容易遗漏。
- 性能差: 同步阻塞IO,在频繁打印时会影响程序性能。
- 无法输出到文件: 程序重启后,日志就没了。
2. SLF4J + Logback 快速上手
- SLF4J:是一个日志门面(接口),它不负责具体实现,让你可以自由切换底层日志框架(如Logback, Log4j2)。
- Logback:是SLF4J的原生实现,性能很好,是Log4j的升级版。
3. 基本配置和使用
- Maven依赖:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>- 在
src/main/resources下创建logback.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 文件输出,按天滚动 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/myapp.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/myapp.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory> <!-- 保留30天 -->
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 设置日志级别 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</configuration>- 在代码中使用:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service
public class MyService {
// 推荐用当前类来创建Logger
private static final Logger logger = LoggerFactory.getLogger(MyService.class);
public void doSomething() {
logger.info("业务方法开始执行...");
try {
// 业务逻辑
logger.debug("这是一个调试信息:{}", someVariable); // 使用占位符,性能更好
} catch (Exception e) {
logger.error("处理业务时发生错误:", e); // 一定要打印异常栈!
}
}
}总结:
学会打日志是程序员成熟的标志之一。好的日志能让你在问题发生时快速定位,而不是像个无头苍蝇。从今天起,告别System.out.println吧!