日常妙招屋
白蓝主题五 · 清爽阅读
首页  > 网络监控

参数校验日志记录有必要吗

你有没有遇到过这种情况:用户提交了一个表单,系统报错,但查来查去就是找不到问题出在哪。最后发现,原来是前端传了个空字符串,后端没做校验,直接崩了。这种时候,光靠错误堆栈根本不够用,得看当时到底传了啥参数才行。

参数校验日志,本来就不该分开看

很多人觉得,只要把参数校验写好,不合法的数据拦住就完事了。可现实是,再严密的校验也挡不住千奇百怪的输入。尤其是对外接口,谁都能调,手机端、网页端、第三方脚本,五花八门。你规定必须传数字,结果人家传了个“undefined”字符串,你不记日志,怎么知道是谁的问题?

举个例子,公司内部有个订单创建接口,某天突然大量失败。排查时发现是某个字段格式不对。可前端说他们没改,后端查代码也没动过。最后翻到一条日志,看到某个请求的参数是“{\"amount\": \"ten\"}”,这才发现是新上的小程序把英文金额传过来了。要不是这条日志,估计还得吵几天锅是谁的。

日志不是越多越好,但关键地方不能省

当然,也不是每个参数都得打一遍日志。那样磁盘扛不住,查起来也像大海捞针。重点是记那些可能出问题的地方:外部输入、敏感操作、核心业务流程。比如登录、支付、数据导出,这些环节的参数,记一下成本不高,但关键时刻能救命。

而且日志内容也得讲究。别一股脑把整个请求体全打出来,既浪费空间又可能泄露隐私。可以只记录关键字段,或者脱敏后再存。比如手机号保留前三位,身份证打码,密码类字段直接忽略。

实际怎么写才合理

下面是个简单的 Java 示例,用 Spring Boot 写接口时加点日志:

@PostMapping("/user/create")
public ResponseEntity<String> createUser(@RequestBody UserRequest request) {
    log.info("收到用户创建请求,参数: name={}, age={}, phone={}", 
             request.getName(), 
             request.getAge(), 
             maskPhone(request.getPhone()));

    if (request.getName() == null || request.getName().trim().isEmpty()) {
        log.warn("用户创建失败,姓名为空,完整请求参数未记录,仅保留标识: traceId={}", generateTraceId());
        return ResponseEntity.badRequest().body("姓名不能为空");
    }
    
    // 其他处理...
}

这里用了 maskPhone 方法对手机号脱敏,同时在出错时补一条警告日志,方便后续追踪。traceId 可以帮助关联一整条调用链,比单纯看时间戳准得多。

其实在日常运维中,很多小问题都是靠这类细节撑过去的。你不会天天翻日志,但一旦出事,有和没有,完全是两种节奏。参数校验挡住的是明显错误,而日志记录帮你抓住那些“理论上不可能发生”的意外。