在从后端向全栈转型的过程中,我们往往容易陷入一个误区:认为日志就是程序的“录像机”,必须记录下每一个执行步骤。但实际上,在企业级开发中,日志更像是一个“黑匣子”。
今天,我们就来深度复盘一下,如何剔除那些无效的“噪音日志”,构建一套真正能用于线上排查的日志体系。
一、核心判断标准:凌晨三点的测试
判断一行日志该不该写,只需要问自己一个问题:如果凌晨 3 点线上告警,我被电话叫起来排查,这行日志能不能帮我还原现场?
- 能 → 写。
- 不能 → 删。
飞机黑匣子不会录下飞行员说的每句话,只记录关键仪表数据和操作事件。同理,日志应当记录“出问题时需要的线索”,而不是“程序执行的每一步”。
二、企业级日志的“七大铁律”
在真实的业务场景中,日志的价值在于信息密度。以下是企业开发中必须保留日志的七个关键位置:
- Catch 异常处(最高优先级)
这是日志价值最高的地方,因为异常代表了“已经出问题”的现场。
- 规范:业务关键参数 + 完整堆栈(将异常对象
e放在最后一个参数)。 - 最佳实践:Controller 层通常不写 try-catch,而是抛给全局异常处理器统一打 ERROR,避免代码冗余。
- 调用外部依赖的前后
这是区分“我的锅”还是“下游的锅”的关键分水岭。
- 场景:HTTP、RPC、MQ、第三方接口。
- 规范:凡是跨进程边界的调用,出入参都要留痕。例如调用微信支付下单,必须记录请求参数和返回结果。
- 关键业务动作
涉及资金、权限、状态变更的操作,必须满足审计和追溯需求。
- 场景:下单、支付、退款、登录、改密码、审批等。
- 规范:记录“发生过”这件事本身。企业通常会配合“操作日志表”使用,日志文件负责技术排查,数据库表负责业务审计。
- 定时任务与批处理
无人值守的代码出了问题没人知道,因此必须有头有尾。
- 规范:任务开始时打日志,结束时记录总数、成功数、失败数及耗时。
- 非预期分支(WARN 的主战场)
当程序走到降级、重试、兜底或参数修正的分支时,虽然没报错,但“不对劲”。
- 规范:使用 WARN 级别。例如缓存与数据库均未命中时,记录返回了游客身份。
- 超阈值的慢操作
不要给每个方法计时,只在超过阈值时记录。
- 规范:例如查询耗时超过 200ms 时打一行 WARN。企业更常见的做法是直接利用 Druid 或 Micrometer 统一采集慢 SQL。
- 启动时的关键环境信息
- 规范:记录连接了哪个库、注册到了哪个中心。Spring Boot 启动 Banner 通常自带这些信息,自定义组件初始化失败时需补充。
三、明确不该加日志的“雷区”
日志是有存储和检索成本的。在 QPS 较高的生产环境,多余的日志会导致磁盘IO飙升。
- 简单查询的成功路径:无信息量,纯噪音。
- Controller 方法开头的“收到请求”:这属于横切关注点,应由 Filter、Interceptor 或网关统一记录(URI、耗时、状态码)。
- 循环内部:如果循环 1 万条数据刷 1 万行日志,真出问题也会被淹没;应改为循环外打汇总。
- 敏感信息:密码、身份证、完整手机号,打了就是安全事故。
四、各层级的分工惯例
一个清晰的分层日志设计,能让排查效率事半功倍:
- 网关 / Nginx:记录谁在什么时候访问了什么接口、状态码、耗时。
- Filter / Interceptor:处理 traceId、统一入参出参(DEBUG 级别)。
- Controller:几乎不写日志,只做参数校验和转发。
- Service:关键业务节点 INFO、外部调用留痕、异常 ERROR。
- Mapper / DAO:不手写,开启框架的慢 SQL / SQL 日志。
- 全局异常处理器:所有未捕获异常的 ERROR 兜底。
五、实战对比:从“教学版”到“企业版”
让我们看一个真实的对比案例。
教学演示版(噪音满满):
@GetMapping
public List<User> listUsers() {
log.info("收到查询用户列表请求,来自 unknown");
log.info("开始查询用户列表");
long start = System.currentTimeMillis();
List<User> users = userService.listUsers();
log.info("查询完成,共 {} 条,耗时 {} ms", users.size(), System.currentTimeMillis() - start);
log.info("返回响应:{}", users);
return users;
}
企业真实版(干干净净):
@GetMapping
public List<User> listUsers() {
return userService.listUsers(); // 一行日志都没有
}
配合全局异常处理器兜底 ERROR、拦截器统一记录访问日志、MyBatis 配置 SQL 日志。业务代码干干净净,出问题时信息反而一个都不少——因为该在统一层记录的都在统一层。
六、记忆口诀
异常必打、外调留痕、关键业务可审计、批处理有头有尾、非预期分支用 WARN;正常路径不说话。
日志框架的配置只是基础,真正的功力在于对“排错现场”的想象力。多看几次真实故障的排查过程,你自然就能掌握这门“黑匣子”的艺术。

306

被折叠的 条评论
为什么被折叠?



