你的日志正在"裸奔"吗?80%的线上问题都因它而起!
每天5分钟,掌握一个SpringBoot核心知识点。大家好,我是SpringBoot指南的小坏。前两天我们讲了限流保护系统,今天聊点更基础的——日志。别小看日志,线上问题排查80%靠它!
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java,获取本文所有示例代码、配置模板及导出工具。
真实故事:一个差点让我失业的日志事故
上个月,我们线上系统出了个大问题:
周一 9:00 用户反馈:"订单支付后一直没反应..."
客服回复:"可能是网络延迟,请稍等"
周二 14:00 同样问题的用户增加到200多人
开发排查:日志里只有一句"支付失败"
周三 10:00 老板在群里@我:"为什么这么多用户付不了款?"
紧急排查:翻遍了3个G的日志文件,找不到原因
周三 15:00 运营总监发飙:"已经损失1000订单了!"
最终发现:第三方支付接口改了,但日志没记录错误详情
教训:不会打日志的程序员,就像蒙着眼睛开车——迟早出事!
一、你的日志在"裸奔"吗?
先做个快速自测:
✅ 你是不是还在用 System.out.println() 打日志?
✅ 异常是不是只打印了 e.getMessage()?
✅ 日志文件是不是已经几十G了还没清理?
✅ 线上出了问题是不是要 grep 半天?
如果中了2条以上,你的日志就在"裸奔"!下面我教你穿上"防弹衣"。
二、3分钟基础配置,告别裸奔
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java,获取本文所有示例代码、配置模板及导出工具。
在 application.yml 里加这几行:
# 基础防护三件套
logging:
# 1. 日志文件自动分割(避免文件过大)
file:
name: logs/app.log
max-size: 10MB # 超过10M就切分
max-history: 30 # 只保留30天日志
# 2. 不同环境不同级别
level:
com.yourapp.service: DEBUG # 自己代码看详细
root: INFO # 其他只看重要信息
# 3. 给日志加"身份证"(方便追踪)
pattern:
console: "%d{HH:mm:ss} [%thread] %-5level - %msg%n"
效果:
- 日志自动按10M分割,不会撑爆磁盘
- 开发时看详细日志,线上只看重要信息
- 每条日志都有时间、线程、级别,一目了然
三、4种日志级别,别用错了!
简单理解成4个等级:
1. DEBUG(调试日志)—— 给开发看的
// 开发时用,上线后关掉
log.debug("SQL语句:SELECT * FROM user WHERE id = {}", id);
2. INFO(信息日志)—— 正常业务流程
// 用户做了什么,结果如何
log.info("用户注册成功,手机号:{},注册时间:{}", phone, time);
3. WARN(警告日志)—— 有点小问题
// 需要注意,但不紧急
log.warn("接口响应较慢,耗时:{}ms,用户ID:{}", 1500, userId);
4. ERROR(错误日志)—— 出大事了!
// 一定要记录完整异常!
try {
// 业务代码
} catch (Exception e) {
log.error("支付失败!订单号:{},用户:{}", orderNo, userId, e);
// 注意:这里e一定要传进去!
}
关键原则:
- 用户关键操作 → 用 INFO
- 第三方调用异常 → 用 ERROR + 完整异常
- 性能问题 → 用 WARN
- 敏感信息 → 一定要脱敏!
四、避坑指南:这些坑我都踩过
坑1:磁盘被日志撑爆
// ❌ 错误:循环里狂打日志
for (int i = 0; i < 100000; i++) {
log.info("处理第{}条数据...", i); // 产生10万行日志!
}
// ✅ 正确:批量处理记录
log.info("开始批量处理,共{}条数据", total);
// 处理逻辑...
log.info("批量处理完成,成功{}条", successCount);
坑2:找不到用户的操作记录
// ❌ 错误:没有用户标识
log.info("用户提交了订单"); // 哪个用户???
// ✅ 正确:加上用户ID
log.info("用户提交订单,用户ID:{},订单号:{}", userId, orderNo);
坑3:密码等敏感信息泄露
// ❌ 危险:明文记录密码
log.info("用户登录,账号:{},密码:{}", "admin", "123456");
// ✅ 安全:脱敏处理
public String maskPhone(String phone) {
return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
}
log.info("用户登录,手机号:{}", maskPhone("13800138000"));
五、高级技巧:让排查效率提升10倍
技巧1:给请求加"身份证号"
// 在拦截器中生成唯一ID
String traceId = UUID.randomUUID().toString();
MDC.put("traceId", traceId);
// 日志自动带上这个ID
logging:
pattern: "%d{yyyy-MM-dd HH:mm:ss} [%traceId] %msg%n"
// 输出:2024-01-15 10:30:00 [abc-123] 用户登录成功
技巧2:不同模块日志分开存
# 用户模块日志存user.log
logging:
config: classpath:logback-spring.xml
<!-- logback-spring.xml -->
<appender name="USER_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/user.log</file>
</appender>
<logger name="com.yourapp.user" level="INFO">
<appender-ref ref="USER_FILE"/>
</logger>
技巧3:集成ELK,像百度一样搜日志
# 用Docker一键启动ELK
docker-compose up -d elasticsearch logstash kibana
- 🔍 像搜百度一样搜日志
- 📊 图表分析错误趋势
- 📱 微信接收错误告警
六、一套完整的配置方案
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
# application.yml
spring:
application:
name: user-service
logging:
# 基础设置
level:
root: INFO
com.yourapp: DEBUG
# 文件设置
file:
name: logs/${spring.application.name}.log
max-size: 50MB
max-history: 60
# 格式设置
pattern:
console: "%d{HH:mm:ss} %highlight(%-5level) %cyan(%logger{20}) - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{40} - %msg%n"
# 特殊配置
logback:
rollingpolicy:
# 错误日志单独文件
error-file: logs/error.log
error-max-size: 100MB
七、今日思考题
场景:你的电商系统突然收到大量用户投诉"支付失败",但监控显示系统正常。
问题:
- 你会如何快速定位问题?
- 需要查看哪些日志?
- 如何避免下次再出现类似问题?
在评论区分享你的排查思路,点赞最高的3位送《线上问题排查实战手册》!
下期预告:《你的SpringBoot应用真的"健康"吗?监控方案来了!》—— 不用等用户投诉,自己就能发现问题!
限时福利:关注公众号回复"日志模板",领取我用了3年的Logback配置模板,开箱即用!
公众号运营小贴士:
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
💡 互动设计:
- 话题讨论:你因为日志吃过最大的亏是什么?
- 投票:你们团队有日志规范吗?
- 经验征集:分享你的日志排查技巧,抽3位送技术书籍
🎁 粉丝福利:
- 关注后回复"日志规范",获取完整开发规范文档
- 转发到3个技术群,截图领《Java性能优化手册》
👥 社群引导: "遇到日志难题?加我微信进SpringBoot实战群,和3000+开发者一起进步!"
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
🔥 明日预告: "不用等用户投诉!SpringBoot健康监控方案明天见"