json打印实现日志统一脱敏
1. 背景
项目已经快完成了,有统一的日志拦截器打印日志,要求对日志关键字脱敏,网络链路输入输出不要求脱敏
项目中对关键字的定义比较规范,如:身份证号 cardId 密码:password
2. 脱敏方式选择
当下从网上找到或者我知道的脱敏方式:
-
logback 或log4j 日志匹配脱敏:大概原理是在日志输出时匹配信息,如手机号,如果用正则匹配到了,就隐藏脱敏
- 优点:统一拦截,不需要大量时间梳理代码
- 缺点:可能导致误脱敏,将一些本来不需要的数据脱敏
-
注解脱敏:在敏感字段上加上注解,在输出日志是拦截脱敏
- 优点:精准脱敏
- 缺点:代码梳理,新人新代码容易忘记加注解
-
jackson 或 fastjson 针对指定字段统一拦截脱敏(只是将注解替换成了自定义)
- 优点:精准脱敏,字段可配置
- 缺点:代码梳理
以下使用jackson和fastjson分别实现,主要还是看代码,我们代码中使用了@jsonformat等jackson注解,所以采用jackson方式
3.jackson代码编写
LogJsonUtil.java
package org.gyx.sbmcommon.utils.test;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 基于jackson针对日志脱敏的打印工具类
*/
public class LogJsonUtil {
private static ObjectMapper mapper = new ObjectMapper();
static {
// 注册处理敏感字段的扩展模块
mapper.registerModule(new SensitiveFieldProcessModule());
}
/**
* 针对日志做脱敏处理,不建议其他地方使用
* @param obj
* @return java.lang.String
**/
public static String log2Json(Object obj){
if (obj == null){
return null;
}
String jsonString = null;
try{
jsonString = mapper.writeValueAsString(obj);
}
catch(IOException e){
}
return jsonString;
}
//测试
public static void main(String[] args) {
UserInfo info = new UserInfo("张三", 11, "18076543241",
"622223199309238976", "qwerasdf", "宇宙洪荒");
System.out.println(log2Json(info));
List<UserInfo> list = new ArrayList<>();
list.add(new UserInfo("张三", 11, "18076543241",
"622223199309238976", "qwerasdf", "宇宙洪荒"));
list.add(new UserInfo("张麻子", 11, "18076543241",
"622223199309238976", "qwerasdf", "宇宙洪荒"));
System.out.println(log2Json(list));
}
@Data
static class UserInfo{
private String name;
private int age;
private String telephone;
private String cardId;
private String password;
private String ad