第1章:原始时代------System.out.println的局限性
typescript
// 新手村标准写法
public static void main(String[] args) {
System.out.println("程序启动啦!"); // 简单但粗糙
// 问题1:无法控制输出级别
// 问题2:性能低下(同步阻塞)
// 问题3:无法输出到文件
// 问题4:没有上下文信息(时间、类名等)
}
第2章:青铜时代------JDK自带日志框架
java
import java.util.logging.Logger;
import java.util.logging.Level;
public class BasicLogging {
private static final Logger LOG = Logger.getLogger(BasicLogging.class.getName());
public static void main(String[] args) {
LOG.info("订单创建成功"); // 基础分级
LOG.log(Level.SEVERE, "数据库连接失败", new Exception("Connection timeout"));
// 优点:自带分级
// 缺点:配置复杂、功能有限
}
}
第3章:工业革命------主流日志框架对决
方案1:Log4j2(性能王者)
xml
<!-- pom.xml -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4jDemo {
private static final Logger logger = LogManager.getLogger();
public void processOrder() {
logger.debug("订单明细:{}", orderDetails); // 参数化日志
logger.error("支付失败", exception);
}
}
方案2: Logback (SpringBoot官方推荐)
xml
<!-- logback.xml -->
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
</root>
</configuration>
第4章: 最佳实践 ------日志框架的正确打开方式
1. 统一日志门面(SLF4J)
xml
<!-- 使用SLF4J统一接口 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<!-- 具体实现(以Logback为例) -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.8</version>
</dependency>
2. 参数化日志(性能优化关键)
arduino
// 错误写法(浪费性能):
logger.debug("User info: " + user);
// 正确姿势:
logger.debug("User info: {}", user); // 延迟字符串拼接
3. 日志级别规范
级别 | 使用场景 |
---|---|
TRACE | 最细粒度调试信息(如循环内部状态) |
DEBUG | 开发调试信息(线上环境关闭) |
INFO | 重要业务流程节点 |
WARN | 潜在问题(如缓存即将过期) |
ERROR | 业务异常(需要人工介入) |
第5章:高级技巧------让日志成为调试神器
1. MDC 实现链路追踪
perl
// 在请求入口处:
MDC.put("traceId", UUID.randomUUID().toString());
// 日志模板添加%X{traceId}:
<pattern>%d{ISO8601} [%X{traceId}] %-5level %logger{36} - %msg%n</pattern>
2. 异步日志(性能提升10倍+)
xml
<!-- log4j2异步配置 -->
<AsyncLogger name="com.your.package" level="debug" additivity="false">
<AppenderRef ref="Console"/>
</AsyncLogger>
3. 敏感信息脱敏
scala
public class SensitiveConverter extends ClassicConverter {
@Override
public String convert(ILoggingEvent event) {
return event.getMessage()
.replaceAll("("password":")(.*?)(")", "$1****$3");
}
}
终极方案:日志系统迁移路线图
-
第一步:全局替换System.out
bash# 使用IDE正则替换: System.out.println((.*)); → log.info("{}", $1);
-
第二步:配置日志框架(选择其一)
-
Log4j2:追求极致性能
-
Logback:SpringBoot生态友好
-
-
第三步:接入集中式日志系统
bash# ELK(Elasticsearch+Logstash+Kibana)架构: 应用 → Logstash → Elasticsearch → Kibana展示
日志哲学:
**好的日志系统应该像优秀的新闻记者------
-
在正确的时间(及时)
-
用正确的角度(上下文)
-
报道重要的事实(关键信息)
-
并且绝不添油加醋(性能消耗低)**