看到这种代码,我直接气到想打人

1. 背景

上周五11点,上游业务急匆匆的拉我入群,说有一个大客户反馈,他们账户无缘无故不能下单了。

多大的客户呢?真的非常大,看了下他的账户授信额度上千万的级别,这个客户大家绝对都听说过(做物流的一哥)。

吓得我开会的心情的都没了,直接去日志平台排查问题。不看不知道,一看我的血压直接飙升,心里开始骂人了。

这个系统是离职的同学暂时交给我的,现在处于只维护,不新增需求的状态。

2. 代码

简化代码如下:

java 复制代码
@RequestMapping("/pay")
public void pay(PayReq req) {
    // switch 读取阿波罗配置
    if (switch) {  
       aPay(req);
    } else {
       bPay(req);
    }
}

public void aPay(PayReq req) {
    // 里面去查了3-4张数据表,涉及5-6个阿波罗字段,才确定是哪个实现类
    // payService 下面有5个继承 serviceA, serviceB, serviceC, serviceD, serviceE...
    payServiceA = xxxSelect.getPayService(req);  
    payServiceA.pay(req);  // 里面至少5-6个rpc调用
}

看代码,我头都懵了,这下单的逻辑这么复杂,涉及到5-6个系统,10几个数据库表,好几个不同的实现类,几十个阿波罗的配置,分支绕来绕去。

但是日志平台的 日志只有 3 行!!! \color{red}{日志只有3行!!!} 日志只有3行!!! 没错,只有3行,我当时都懵了,这shabi写代码的人,怎么一行日志都不打印,这特么怎么看。

我甚至都不知道你走了aPay,还是bPay。你走的哪个payService我都不知道,报错是哪一行我都看不出来。当时真的无从下手。

不过最后客户账号又好了,也不知道原因。当然这不是今天的主题,今天的主题是:如何优雅的打日志

3. 如何优雅的打日志

在Java体系中,日志的实现有很多,logback、log4j等等,网上讲怎么配置的也非常多,推荐不知道怎么配置的可以看看这篇文章 log4j2 异步日志正确配置

今天我想聊一聊在真正的生产环境中,如何打日志,哪些地方需要打日志,哪些地方不需要打日志,如何优雅的打日志,这可是血与泪的教训中形成的。

3.1 如何打日志

一个合格的日志必须具备以下要素。具体的时间、日志级别、全局traceId,类名+方法名 + 具体行数 + 具体的内容,尤其是全局traceId,必备。

shell 复制代码
###|||2025-06-01 17:53:36.000|||INFO|||[全局traceId]()|||http-nio-8080-exec-7|||ClassName|||methodName|||182---> 具体日志内容

3.2 哪些地方需要打日志

  1. 方法的入口必须打日志。比如controller开头,controller结尾。当然你也可以使用aop全局打印日志。
  2. 有分支逻辑之前必须打日志。比如你从阿波罗里面读取的配置 if (switch) {xxx} ,又比如你整合了所有数据,最后判断走a逻辑还是b逻辑
  3. 如果涉及到策略模式、模板模式等设计模式,必须明确打印出,走的是哪个具体的service方法,否则给其他人或者排查问题,会带来很大的困扰
  4. 调用RPC前后必须打日志,比如 log.info("req = {}", req), doXXX,log.info("res = {}", res),如果如果调用失败,抛异常,必须把完整的栈链路打印出来
  5. 从数据库获取的数据必须打日志。因为数据库的状态可能会变,比如客户的账号status信息,必须是当时的那个时点的状态信息,而不是在从数据库捞数据,是不准确的。
  6. 重要数据、上下文数据、一些状态等重要信息必须打日志
  7. 建议打日志req bo等使用json,比如 log.info("req = {}", JSON.toJsonString(req)),这样排查问题格式化比较方便
  8. 有些公司的日志平台限制长度,比如1000个字符等等,注意长度
  9. 宁可多打,也不要少打,因为少打日志,对排查问题难度太大了。

4. 最后

刚毕业在第一家公司的时候,由于项目比较大,本地是启动不了的、不能debug。只能在stg、pre等环境启动,也就养成了我看日志的习惯,也慢慢锻炼了我排查问题的水平。

因此也希望大家养成打日志的好习惯,不要自己的代码被其他人接手的时候,还要被骂这不行那不行的,这样口碑会非常不好的。

慢慢去补这个项目的日志了。

相关推荐
喜欢打篮球的普通人13 分钟前
Trition程序编写:从“Hello CUDA“到“Hello Triton“:向量加法背后的编译黑魔法
开发语言·后端·rust
苏三说技术20 分钟前
Spring AI 2.0和Spring AI Alibaba,哪个更好?
后端
用户67570498850220 分钟前
还在用字符串返回错误提示?Go语言优雅错误处理的正确姿势!
后端·go
雪隐33 分钟前
用Flutter做背单词APP-02我画了设计稿,然后让AI帮我设计了数据库(顺便聊了会天)
前端·人工智能·后端
用户938515635071 小时前
从零打造你的第一个智能体(Agent):*手写一个能自主建项目的Mini Cursor (三)
javascript·人工智能·后端
Alan_751 小时前
GraphQL 深度解析:为什么它能替代传统 REST API
数据库·后端
SamDeepThinking1 小时前
为什么很多人学了Java,还是没真正理解类和对象?
java·后端·面试
逝水无殇1 小时前
C# 多态性详解
开发语言·后端·c#
逝水无殇1 小时前
C# 继承(Inheritance)详解
开发语言·后端·c#
用户938515635071 小时前
手写迷你 Cursor 终端:深入 Node.js child_process 的 spawn 核心实现
javascript·后端