校验失败日志必须结构化记录5类核心字段:traceid、接口路径与方法、dto类名、具体字段及错误原因、脱敏后原始参数;统一用warn级别并添加validation_fail marker。

参数校验失败时,日志不能只打印“校验不通过”或堆栈缩略信息,而要记录足够上下文,便于快速定位问题源头——比如是哪个接口、谁调的、传了什么错数据、具体哪条规则没满足。关键不是记得多,而是记得准、结构化、可检索。
必须包含的5类核心字段
每条校验失败日志应稳定输出以下信息,建议统一封装为结构化 JSON(如用 Logback 的 jsonLayout):
- 请求标识:traceId 或 requestId(需与网关/Feign链路对齐);
-
接口路径与方法:如
POST /api/user/register; -
触发校验的 DTO 类名:如
UserRegisterDTO,避免只写“参数错误”; -
具体字段与错误原因:例如
email: 邮箱格式不正确或password: 密码长度不能少于8位; -
原始请求参数(脱敏后):仅记录关键字段值,敏感字段如密码、手机号做掩码处理(如
"phone": "138****1234")。
避免记录全量 Body 的常见误区
直接打印整个 request body 容易导致日志膨胀、泄露敏感信息、甚至 OOM。正确做法是:
- 不记录未参与校验的字段(如 DTO 中有 20 个字段,只校验了其中 5 个,就只提取这 5 个字段的值);
- 使用 Jackson 的
ObjectMapper+ 自定义序列化器,对已知敏感字段自动脱敏; - 在全局异常处理器中,从
BindingResult获取FieldError后,再反查原始参数对象对应字段值,而非解析原始 JSON 字符串。
日志级别与分类建议
校验失败属于**业务预期异常**,不是系统故障,因此:
- 统一用 WARN 级别,不使用 ERROR(避免触发告警误报);
- 添加固定 marker,如
VALIDATION_FAIL,方便 ELK/Kibana 中按 marker 聚合过滤; - 在日志内容开头加标识,例如:
[VALIDATION_FAIL] POST /api/order/create — email: 非法邮箱格式,param={email:'test@', phone:'139****5678'}。
结合全局异常处理器落地示例
在 @ExceptionHandler(MethodArgumentNotValidException.class) 方法内记录日志,推荐写法:
log.warn(VALIDATION_FAIL_MARKER,
"Validation failed on {} {}: {} — params={}",
request.getMethod(),
request.getRequestURI(),
errors.stream().map(e -> e.getField() + ": " + e.getDefaultMessage()).collect(Collectors.joining("; ")),
maskSensitiveFields(dto));
其中 maskSensitiveFields() 是你封装的脱敏工具方法,VALIDATION_FAIL_MARKER 是预定义的 Logback Marker 实例。











