mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
feat(日志管理): 增加 Jackson json 日志脱敏工具类,如果日志入库中有敏感字段则进行删除
This commit is contained in:
1 parent
c75a491bf5
commit
c246dc397b
5 files changed
+121
-77
No files matched your search
+18
-18
@@ -33,27 +33,27 @@ import java.util.List;
|
||||
@ConfigurationProperties(PigxLogProperties.PREFIX)
|
||||
public class PigxLogProperties {
|
||||
|
||||
public static final String PREFIX = "pigx.log";
|
||||
public static final String PREFIX = "pigx.log";
|
||||
|
||||
/**
|
||||
* 开启日志记录
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
/**
|
||||
* 开启日志记录
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 记录请求报文体
|
||||
*/
|
||||
private boolean requestEnabled = true;
|
||||
/**
|
||||
* 记录请求报文体
|
||||
*/
|
||||
private boolean requestEnabled = true;
|
||||
|
||||
/**
|
||||
* 放行字段,password,mobile,idcard,phone
|
||||
*/
|
||||
@Value("${pigx.log.exclude-fields:password,mobile,idcard,phone}")
|
||||
private List<String> excludeFields;
|
||||
/**
|
||||
* 放行字段,password,mobile,idcard,phone
|
||||
*/
|
||||
@Value("${pigx.log.exclude-fields:password,mobile,idcard,phone,accessSecret,tokenId,sign}")
|
||||
private List<String> excludeFields;
|
||||
|
||||
/**
|
||||
* 请求报文最大存储长度
|
||||
*/
|
||||
private Integer maxLength = 2000;
|
||||
/**
|
||||
* 请求报文最大存储长度
|
||||
*/
|
||||
private Integer maxLength = 2000;
|
||||
|
||||
}
|
||||
+39
-56
@@ -18,16 +18,11 @@ package com.pig4cloud.pigx.common.log.event;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonFilter;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ser.FilterProvider;
|
||||
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
|
||||
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
|
||||
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.jackson.PigxJavaTimeModule;
|
||||
import com.pig4cloud.pigx.common.log.config.PigxLogProperties;
|
||||
import com.pig4cloud.pigx.common.log.util.JacksonSensitiveFieldUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -49,62 +44,50 @@ import java.util.Objects;
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogListener implements InitializingBean {
|
||||
|
||||
/**
|
||||
* 忽略序列化的对象类型
|
||||
*/
|
||||
private final static Class[] ignoreClass = { ServletRequest.class, BindingResult.class };
|
||||
/**
|
||||
* 忽略序列化的对象类型
|
||||
*/
|
||||
private final static Class[] ignoreClass = {ServletRequest.class, BindingResult.class};
|
||||
|
||||
/**
|
||||
* new 一个 避免日志脱敏策略影响全局ObjectMapper
|
||||
*/
|
||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
||||
/**
|
||||
* new 一个 避免日志脱敏策略影响全局ObjectMapper
|
||||
*/
|
||||
|
||||
private final RemoteLogService remoteLogService;
|
||||
private final RemoteLogService remoteLogService;
|
||||
|
||||
private final PigxLogProperties logProperties;
|
||||
private final PigxLogProperties logProperties;
|
||||
|
||||
@SneakyThrows
|
||||
@Async
|
||||
@Order
|
||||
@EventListener(SysLogEvent.class)
|
||||
public void saveSysLog(SysLogEvent event) {
|
||||
SysLogDTO source = (SysLogDTO) event.getSource();
|
||||
@SneakyThrows
|
||||
@Async
|
||||
@Order
|
||||
@EventListener(SysLogEvent.class)
|
||||
public void saveSysLog(SysLogEvent event) {
|
||||
SysLogDTO source = (SysLogDTO) event.getSource();
|
||||
|
||||
// json 格式刷参数放在异步中处理,提升性能
|
||||
if (Objects.nonNull(source.getBody()) && logProperties.isRequestEnabled()) {
|
||||
Object[] args = (Object[]) source.getBody();
|
||||
List<Object> list = CollUtil.toList(args);
|
||||
// 删除部分无法序列化的参数
|
||||
list.removeIf(obj -> Arrays.stream(ignoreClass).anyMatch(clazz -> clazz.isAssignableFrom(obj.getClass())));
|
||||
// json 格式刷参数放在异步中处理,提升性能
|
||||
if (Objects.nonNull(source.getBody()) && logProperties.isRequestEnabled()) {
|
||||
Object[] args = (Object[]) source.getBody();
|
||||
List<Object> list = CollUtil.toList(args);
|
||||
// 删除部分无法序列化的参数
|
||||
list.removeIf(obj -> Arrays.stream(ignoreClass).anyMatch(clazz -> clazz.isAssignableFrom(obj.getClass())));
|
||||
|
||||
try {
|
||||
// 序列化参数
|
||||
String params = objectMapper.writeValueAsString(list);
|
||||
source.setParams(StrUtil.subPre(params, logProperties.getMaxLength()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("请求参数序列化异常:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 序列化参数
|
||||
String params = JacksonSensitiveFieldUtil.getObjectMapper().writeValueAsString(list);
|
||||
source.setParams(StrUtil.subPre(params, logProperties.getMaxLength()));
|
||||
} catch (Exception e) {
|
||||
log.error("请求参数序列化异常:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
source.setBody(null);
|
||||
remoteLogService.saveLog(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class);
|
||||
String[] ignorableFieldNames = logProperties.getExcludeFields().toArray(new String[0]);
|
||||
|
||||
FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name",
|
||||
SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
|
||||
objectMapper.setFilterProvider(filters);
|
||||
objectMapper.registerModule(new PigxJavaTimeModule());
|
||||
}
|
||||
|
||||
@JsonFilter("filter properties by name")
|
||||
class PropertyFilterMixIn {
|
||||
|
||||
}
|
||||
source.setBody(null);
|
||||
remoteLogService.saveLog(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
String[] ignorableFieldNames = logProperties.getExcludeFields().toArray(new String[0]);
|
||||
JacksonSensitiveFieldUtil.configureSensitiveFields(ignorableFieldNames);
|
||||
JacksonSensitiveFieldUtil.registerCustomModule(new PigxJavaTimeModule());
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.pig4cloud.pigx.common.log.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFilter;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ser.FilterProvider;
|
||||
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
|
||||
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
/**
|
||||
* Jackson 脱敏
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2024/07/18
|
||||
*/
|
||||
public class JacksonSensitiveFieldUtil {
|
||||
|
||||
@Getter
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
static {
|
||||
objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class);
|
||||
}
|
||||
|
||||
public static void configureSensitiveFields(String[] ignorableFieldNames) {
|
||||
FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name",
|
||||
SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
|
||||
objectMapper.setFilterProvider(filters);
|
||||
}
|
||||
|
||||
public static void registerCustomModule(com.fasterxml.jackson.databind.Module module) {
|
||||
objectMapper.registerModule(module);
|
||||
}
|
||||
|
||||
/**
|
||||
* string -> object
|
||||
*
|
||||
* @param content 内容
|
||||
* @param valueType 值类型
|
||||
* @return {@link T }
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static <T> T readValue(String content, Class<T> valueType) {
|
||||
return objectMapper.readValue(content, valueType);
|
||||
}
|
||||
|
||||
/**
|
||||
* string -> string
|
||||
*
|
||||
* @param content 内容
|
||||
* @return {@link String }
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static String readStr(String content) {
|
||||
Object o = objectMapper.readValue(content, Object.class);
|
||||
return objectMapper.writeValueAsString(o);
|
||||
}
|
||||
|
||||
@JsonFilter("filter properties by name")
|
||||
private static class PropertyFilterMixIn {
|
||||
}
|
||||
}
|
||||
-3
@@ -23,9 +23,6 @@ import com.pig4cloud.pigx.admin.api.entity.SysLog;
|
||||
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 日志表 Mapper 接口
|
||||
|
||||
+1
@@ -89,6 +89,7 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
|
||||
sysLog.getCreateTime()[1]);
|
||||
}
|
||||
|
||||
wrapper.eq(StrUtil.isNotBlank(sysLog.getServiceId()), SysLog::getServiceId, sysLog.getServiceId());
|
||||
return baseMapper.selectPage(page, wrapper);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user