fix(log/core): 修复访问日志json数组打印

对于请求参数的 json 数组打印和处理的问题修复
适配 json 数组打印处理,json 模块增加 JSONUtil 和
JsonBuilder
This commit is contained in:
吴泽威
2025-04-01 16:44:50 +08:00
parent ca2c88651f
commit 199a83fbea
5 changed files with 529 additions and 22 deletions

View File

@@ -166,14 +166,14 @@ public abstract class AbstractLogHandler implements LogHandler {
AccessLogProperties properties = accessLogContext.getProperties().getAccessLog();
// 是否需要打印 规则: 是否打印开关 或 放行路径
if (!properties.isEnabled() || AccessLogUtils.exclusionPath(accessLogContext.getProperties(), ServletUtils
.getReqPath())) {
.getReqPath())) {
return;
}
// 构建上下文
logContextThread.set(accessLogContext);
String param = AccessLogUtils.getParam(properties);
log.info(param != null ? "[Start] [{}] {} param: {}" : "[Start] [{}] {}", ServletUtils
.getReqMethod(), ServletUtils.getReqPath(), param);
log.info(param != null ? "[Start] [{}] {} param: {}" : "[Start] [{}] {}",
ServletUtils.getReqMethod(), ServletUtils.getReqPath(), param);
}
@Override
@@ -185,7 +185,7 @@ public abstract class AbstractLogHandler implements LogHandler {
try {
Duration timeTaken = Duration.between(logContext.getStartTime(), accessLogContext.getEndTime());
log.info("[End] [{}] {} {} {}ms", ServletUtils.getReqMethod(), ServletUtils.getReqPath(), ServletUtils
.getRespStatus(), timeTaken.toMillis());
.getRespStatus(), timeTaken.toMillis());
} finally {
logContextThread.remove();
}

View File

@@ -17,7 +17,7 @@
package top.continew.starter.log.util;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import top.continew.starter.json.jackson.util.JSONUtil;
import top.continew.starter.log.model.AccessLogProperties;
import top.continew.starter.log.model.LogProperties;
import top.continew.starter.web.util.ServletUtils;
@@ -26,6 +26,7 @@ import top.continew.starter.web.util.SpringWebUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 访问日志工具类
@@ -55,25 +56,24 @@ public class AccessLogUtils {
}
// 参数为空返回空
Map<String, Object> params;
Object params;
try {
params = ServletUtils.getReqParam();
params = ServletUtils.getAccessLogReqParam();
} catch (Exception e) {
return null;
}
if (ObjectUtil.isEmpty(params) || params.isEmpty()) {
if (ObjectUtil.isEmpty(params)) {
return null;
}
// 是否需要对特定入参脱敏
if (properties.isParamSensitive()) {
params = filterSensitiveParams(params, properties.getSensitiveParams());
params = processSensitiveParams(params, properties.getSensitiveParams());
}
// 是否自动截断超长参数值
if (properties.isLongParamTruncate()) {
params = truncateLongParams(params, properties.getLongParamThreshold(), properties
params = processTruncateLongParams(params, properties.getLongParamThreshold(), properties
.getLongParamMaxLength(), properties.getLongParamSuffix());
}
return JSONUtil.toJsonStr(params);
@@ -92,6 +92,25 @@ public class AccessLogUtils {
.anyMatch(resourcePath -> SpringWebUtils.isMatch(path, resourcePath));
}
/**
* 处理敏感参数,支持 Map 和 List<Map<String, Object>> 类型
*
* @param params 参数
* @param sensitiveParams 敏感参数列表
* @return 处理后的参数
*/
private static Object processSensitiveParams(Object params, List<String> sensitiveParams) {
if (params instanceof Map) {
return filterSensitiveParams((Map<String, Object>)params, sensitiveParams);
} else if (params instanceof List) {
return ((List<?>)params).stream()
.filter(item -> item instanceof Map)
.map(item -> filterSensitiveParams((Map<String, Object>)item, sensitiveParams))
.collect(Collectors.toList());
}
return params;
}
/**
* 过滤敏感参数
*
@@ -106,11 +125,34 @@ public class AccessLogUtils {
Map<String, Object> filteredParams = new HashMap<>(params);
for (String sensitiveKey : sensitiveParams) {
filteredParams.computeIfPresent(sensitiveKey, (key, value) -> "***");
if (filteredParams.containsKey(sensitiveKey)) {
filteredParams.put(sensitiveKey, "***");
}
}
return filteredParams;
}
/**
* 处理超长参数,支持 Map 和 List<Map<String, Object>> 类型
*
* @param params 参数
* @param threshold 截断阈值(值长度超过该值才截断)
* @param maxLength 最大长度
* @param suffix 后缀(如 "..."
* @return 处理后的参数
*/
private static Object processTruncateLongParams(Object params, int threshold, int maxLength, String suffix) {
if (params instanceof Map) {
return truncateLongParams((Map<String, Object>)params, threshold, maxLength, suffix);
} else if (params instanceof List) {
return ((List<?>)params).stream()
.filter(item -> item instanceof Map)
.map(item -> truncateLongParams((Map<String, Object>)item, threshold, maxLength, suffix))
.collect(Collectors.toList());
}
return params;
}
/**
* 截断超长参数
*