refactor(log): 优化访问日志相关配置属性名称

This commit is contained in:
2025-03-25 22:16:43 +08:00
parent da5e162a2a
commit 4c385927b4
14 changed files with 159 additions and 147 deletions

View File

@@ -23,12 +23,6 @@
<artifactId>spring-boot-configuration-processor</artifactId> <artifactId>spring-boot-configuration-processor</artifactId>
</dependency> </dependency>
<!-- servlet包 -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<!-- Hibernate Validator --> <!-- Hibernate Validator -->
<dependency> <dependency>
<groupId>org.hibernate.validator</groupId> <groupId>org.hibernate.validator</groupId>
@@ -65,5 +59,12 @@
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId> <artifactId>hutool-http</artifactId>
</dependency> </dependency>
<!-- Jakarta原 Javax Servlet -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<optional>true</optional>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -33,8 +33,8 @@ import java.nio.charset.StandardCharsets;
* 支持文件流直接透传,非文件流可重复读取 * 支持文件流直接透传,非文件流可重复读取
* *
* @author echo * @author echo
* @since 2025/03/25 11:11 * @since 2.10.0
**/ */
public class RepeatReadRequestWrapper extends HttpServletRequestWrapper { public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {
private byte[] cachedBody; private byte[] cachedBody;
@@ -50,13 +50,6 @@ public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {
} }
} }
/**
* 检查是否为文件上传请求
*/
private boolean isMultipartContent(HttpServletRequest request) {
return request.getContentType() != null && request.getContentType().toLowerCase().startsWith("multipart/");
}
@Override @Override
public ServletInputStream getInputStream() throws IOException { public ServletInputStream getInputStream() throws IOException {
// 如果是文件上传,直接返回原始输入流 // 如果是文件上传,直接返回原始输入流
@@ -98,4 +91,14 @@ public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {
} }
return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(cachedBody), StandardCharsets.UTF_8)); return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(cachedBody), StandardCharsets.UTF_8));
} }
/**
* 检查是否为文件上传请求
*
* @param request 请求对象
* @return 是否为文件上传请求
*/
private boolean isMultipartContent(HttpServletRequest request) {
return request.getContentType() != null && request.getContentType().toLowerCase().startsWith("multipart/");
}
} }

View File

@@ -31,14 +31,16 @@ import java.nio.charset.StandardCharsets;
* 支持缓存响应内容,便于日志记录和后续处理 (不缓存SSE) * 支持缓存响应内容,便于日志记录和后续处理 (不缓存SSE)
* *
* @author echo * @author echo
* @since 2025/03/25 11:11 * @author Charles7c
**/ * @since 2.10.0
*/
public class RepeatReadResponseWrapper extends HttpServletResponseWrapper { public class RepeatReadResponseWrapper extends HttpServletResponseWrapper {
private final ByteArrayOutputStream cachedOutputStream = new ByteArrayOutputStream(); private final ByteArrayOutputStream cachedOutputStream = new ByteArrayOutputStream();
private final PrintWriter writer = new PrintWriter(cachedOutputStream, true); private final PrintWriter writer = new PrintWriter(cachedOutputStream, true);
/**
// 是否为流式响应 * 是否为流式响应
*/
private boolean isStreamingResponse = false; private boolean isStreamingResponse = false;
public RepeatReadResponseWrapper(HttpServletResponse response) { public RepeatReadResponseWrapper(HttpServletResponse response) {
@@ -67,8 +69,8 @@ public class RepeatReadResponseWrapper extends HttpServletResponseWrapper {
@Override @Override
public ServletOutputStream getOutputStream() throws IOException { public ServletOutputStream getOutputStream() throws IOException {
checkStreamingResponse(); checkStreamingResponse();
// 对于 SSE 流式响应,直接返回原始响应流,不做额外处理
if (isStreamingResponse) { if (isStreamingResponse) {
// 对于 SSE 流式响应,直接返回原始响应流,不做额外处理
return super.getOutputStream(); return super.getOutputStream();
} }
return new ServletOutputStream() { return new ServletOutputStream() {
@@ -108,6 +110,11 @@ public class RepeatReadResponseWrapper extends HttpServletResponseWrapper {
return writer; return writer;
} }
/**
* 获取缓存的响应内容
*
* @return 缓存的响应内容
*/
public String getResponseContent() { public String getResponseContent() {
if (!isStreamingResponse) { if (!isStreamingResponse) {
writer.flush(); writer.flush();
@@ -116,12 +123,22 @@ public class RepeatReadResponseWrapper extends HttpServletResponseWrapper {
return null; return null;
} }
/**
* 将缓存的响应内容复制到原始响应中
*
* @throws IOException IO 异常
*/
public void copyBodyToResponse() throws IOException { public void copyBodyToResponse() throws IOException {
if (!isStreamingResponse && cachedOutputStream.size() > 0) { if (!isStreamingResponse && cachedOutputStream.size() > 0) {
getResponse().getOutputStream().write(cachedOutputStream.toByteArray()); getResponse().getOutputStream().write(cachedOutputStream.toByteArray());
} }
} }
/**
* 是否为流式响应
*
* @return 是否为流式响应
*/
public boolean isStreamingResponse() { public boolean isStreamingResponse() {
return isStreamingResponse; return isStreamingResponse;
} }

View File

@@ -22,8 +22,6 @@ import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import top.continew.starter.log.handler.LogHandler; import top.continew.starter.log.handler.LogHandler;
@@ -44,7 +42,6 @@ import java.time.Instant;
@Aspect @Aspect
public class AccessLogAspect { public class AccessLogAspect {
private static final Logger log = LoggerFactory.getLogger(AccessLogAspect.class);
private final LogProperties logProperties; private final LogProperties logProperties;
private final LogHandler logHandler; private final LogHandler logHandler;
@@ -113,7 +110,8 @@ public class AccessLogAspect {
HttpServletRequest request = attributes.getRequest(); HttpServletRequest request = attributes.getRequest();
HttpServletResponse response = attributes.getResponse(); HttpServletResponse response = attributes.getResponse();
try { try {
logHandler.processAccessLogStartReq(AccessLogContext.builder() // 开始访问日志记录
logHandler.accessLogStart(AccessLogContext.builder()
.startTime(startTime) .startTime(startTime)
.request(new RecordableServletHttpRequest(request)) .request(new RecordableServletHttpRequest(request))
.properties(logProperties) .properties(logProperties)
@@ -121,7 +119,7 @@ public class AccessLogAspect {
return joinPoint.proceed(); return joinPoint.proceed();
} finally { } finally {
Instant endTime = Instant.now(); Instant endTime = Instant.now();
logHandler.processAccessLogEndReq(AccessLogContext.builder() logHandler.accessLogFinish(AccessLogContext.builder()
.endTime(endTime) .endTime(endTime)
.response(new RecordableServletHttpResponse(response, response.getStatus())) .response(new RecordableServletHttpResponse(response, response.getStatus()))
.build()); .build());

View File

@@ -42,6 +42,7 @@ import java.net.URISyntaxException;
* @author Venil NoronhaSpring Boot Actuator * @author Venil NoronhaSpring Boot Actuator
* @author Madhura BhaveSpring Boot Actuator * @author Madhura BhaveSpring Boot Actuator
* @author Charles7c * @author Charles7c
* @author echo
* @since 1.1.0 * @since 1.1.0
*/ */
public class LogFilter extends OncePerRequestFilter implements Ordered { public class LogFilter extends OncePerRequestFilter implements Ordered {
@@ -66,15 +67,15 @@ public class LogFilter extends OncePerRequestFilter implements Ordered {
return; return;
} }
boolean isMatch = logProperties.isMatch(request.getRequestURI()); boolean isExcludeUri = logProperties.isMatch(request.getRequestURI());
// 处理可重复读取的请求 // 处理可重复读取的请求
HttpServletRequest requestWrapper = (isMatch || !this.isRequestWrapper(request)) HttpServletRequest requestWrapper = (isExcludeUri || !this.isRequestWrapper(request))
? request ? request
: new RepeatReadRequestWrapper(request); : new RepeatReadRequestWrapper(request);
// 处理可重复读取的响应 // 处理可重复读取的响应
HttpServletResponse responseWrapper = (isMatch || !this.isResponseWrapper(response)) HttpServletResponse responseWrapper = (isExcludeUri || !this.isResponseWrapper(response))
? response ? response
: new RepeatReadResponseWrapper(response); : new RepeatReadResponseWrapper(response);

View File

@@ -171,11 +171,10 @@ public abstract class AbstractLogHandler implements LogHandler {
} }
@Override @Override
public void processAccessLogStartReq(AccessLogContext accessLogContext) { public void accessLogStart(AccessLogContext accessLogContext) {
AccessLogProperties properties = accessLogContext.getProperties().getAccessLog(); AccessLogProperties properties = accessLogContext.getProperties().getAccessLog();
// 是否需要打印 规则: 是否打印开关 或 放行路径 // 是否需要打印 规则: 是否打印开关 或 放行路径
if (!properties.isPrint() || accessLogContext.getProperties() if (!properties.isPrint() || accessLogContext.getProperties()
.getAccessLog()
.isMatch(accessLogContext.getRequest().getPath())) { .isMatch(accessLogContext.getRequest().getPath())) {
return; return;
} }
@@ -184,22 +183,23 @@ public abstract class AbstractLogHandler implements LogHandler {
RecordableHttpRequest request = accessLogContext.getRequest(); RecordableHttpRequest request = accessLogContext.getRequest();
String path = request.getPath(); String path = request.getPath();
String param = AccessLogUtils.getParam(request, properties); String param = AccessLogUtils.getParam(request, properties);
log.info(param != null ? "[Start] [{}] {} {}" : "[Start] [{}] {}", request.getMethod(), path, param); log.info(param != null ? "[Start] [{}] {} param: {}" : "[Start] [{}] {}", request.getMethod(), path, param);
} }
@Override @Override
public void processAccessLogEndReq(AccessLogContext accessLogContext) { public void accessLogFinish(AccessLogContext accessLogContext) {
AccessLogContext logContext = logContextThread.get(); AccessLogContext logContext = logContextThread.get();
if (ObjectUtil.isNotEmpty(logContext)) { if (ObjectUtil.isEmpty(logContext)) {
try { return;
RecordableHttpRequest request = logContext.getRequest(); }
RecordableHttpResponse response = accessLogContext.getResponse(); try {
Duration timeTaken = Duration.between(logContext.getStartTime(), accessLogContext.getEndTime()); RecordableHttpRequest request = logContext.getRequest();
log.info("[End] [{}] {} {} {}ms", request.getMethod(), request.getPath(), response RecordableHttpResponse response = accessLogContext.getResponse();
.getStatus(), timeTaken.toMillis()); Duration timeTaken = Duration.between(logContext.getStartTime(), accessLogContext.getEndTime());
} finally { log.info("[End] [{}] {} {} {}ms", request.getMethod(), request.getPath(), response.getStatus(), timeTaken
logContextThread.remove(); .toMillis());
} } finally {
logContextThread.remove();
} }
} }
} }

View File

@@ -30,6 +30,7 @@ import java.util.Set;
* 日志处理器 * 日志处理器
* *
* @author Charles7c * @author Charles7c
* @author echo
* @since 2.8.0 * @since 2.8.0
*/ */
public interface LogHandler { public interface LogHandler {
@@ -100,16 +101,18 @@ public interface LogHandler {
Set<Include> getIncludes(Set<Include> includes, Method targetMethod, Class<?> targetClass); Set<Include> getIncludes(Set<Include> includes, Method targetMethod, Class<?> targetClass);
/** /**
* 处理访问日志开始请求 * 开始访问日志记录
* *
* @param accessLogContext 访问日志上下文 * @param accessLogContext 访问日志上下文
* @since 2.10.0
*/ */
void processAccessLogStartReq(AccessLogContext accessLogContext); void accessLogStart(AccessLogContext accessLogContext);
/** /**
* 处理访问日志 结束请求 * 结束访问日志记录
* *
* @param accessLogContext 访问日志上下文 * @param accessLogContext 访问日志上下文
* @since 2.10.0
*/ */
void processAccessLogEndReq(AccessLogContext accessLogContext); void accessLogFinish(AccessLogContext accessLogContext);
} }

View File

@@ -25,6 +25,7 @@ import java.util.Map;
* @author Andy WilkinsonSpring Boot Actuator * @author Andy WilkinsonSpring Boot Actuator
* @author Phillip WebbSpring Boot Actuator * @author Phillip WebbSpring Boot Actuator
* @author Charles7c * @author Charles7c
* @author echo
* @see RecordableHttpResponse * @see RecordableHttpResponse
* @since 1.1.0 * @since 1.1.0
*/ */
@@ -45,11 +46,13 @@ public interface RecordableHttpRequest {
URI getUrl(); URI getUrl();
/** /**
* 获取 IP * 获取路径
* <p>/foo/bar</p>
* *
* @return IP * @return 路径
* @since 2.10.0
*/ */
String getIp(); String getPath();
/** /**
* 获取请求头 * 获取请求头
@@ -73,9 +76,9 @@ public interface RecordableHttpRequest {
Map<String, Object> getParam(); Map<String, Object> getParam();
/** /**
* 获取路径 - 格式 /system/dept * 获取 IP
* *
* @return {@link String } * @return IP
*/ */
String getPath(); String getIp();
} }

View File

@@ -35,6 +35,8 @@ import java.util.Map;
* *
* @author Andy WilkinsonSpring Boot Actuator * @author Andy WilkinsonSpring Boot Actuator
* @author Charles7c * @author Charles7c
* @author echo
* @since 1.1.0
*/ */
public final class RecordableServletHttpRequest implements RecordableHttpRequest { public final class RecordableServletHttpRequest implements RecordableHttpRequest {
@@ -66,8 +68,8 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest
} }
@Override @Override
public String getIp() { public String getPath() {
return JakartaServletUtil.getClientIP(request); return request.getRequestURI();
} }
@Override @Override
@@ -90,8 +92,8 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest
} }
@Override @Override
public String getPath() { public String getIp() {
return request.getRequestURI(); return JakartaServletUtil.getClientIP(request);
} }
private StringBuilder appendQueryString(String queryString) { private StringBuilder appendQueryString(String queryString) {

View File

@@ -30,6 +30,8 @@ import java.util.Map;
* *
* @author Andy WilkinsonSpring Boot Actuator * @author Andy WilkinsonSpring Boot Actuator
* @author Charles7c * @author Charles7c
* @author echo
* @since 1.1.0
*/ */
public final class RecordableServletHttpResponse implements RecordableHttpResponse { public final class RecordableServletHttpResponse implements RecordableHttpResponse {

View File

@@ -25,7 +25,7 @@ import java.time.Instant;
* 访问日志上下文 * 访问日志上下文
* *
* @author echo * @author echo
* @since 2.8.3 * @since 2.10.0
*/ */
public class AccessLogContext { public class AccessLogContext {
@@ -90,7 +90,11 @@ public class AccessLogContext {
return new Builder(); return new Builder();
} }
/**
* 访问日志上下文构建者
*/
public static class Builder { public static class Builder {
private Instant startTime; private Instant startTime;
private Instant endTime; private Instant endTime;
private RecordableHttpRequest request; private RecordableHttpRequest request;

View File

@@ -16,76 +16,71 @@
package top.continew.starter.log.model; package top.continew.starter.log.model;
import top.continew.starter.web.util.SpringWebUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* 访问日志输出配置 * 访问日志配置属性
* *
* @author echo * @author echo
* @since 2.8.3 * @author Charles7c
* @since 2.10.0
*/ */
public class AccessLogProperties { public class AccessLogProperties {
/** /**
* 是否打印日志,开启后可打印访问日志(类似于 Nginx access log * 是否打印访问日志(类似于 Nginx access log
* <p> * <p>
* 不记录日志也支持开启打印访问日志 * 不记录请求日志也支持开启打印访问日志
* </p> * </p>
*/ */
private boolean isPrint = false; private boolean isPrint = false;
/** /**
* 放行路由 * 是否打印请求参数body/query/form
* <p>开启后,访问日志会打印请求参数</p>
*/ */
private List<String> excludePatterns = new ArrayList<>(); private boolean isPrintRequestParam = false;
/**
* 是否记录请求参数body/query/form
* <p>开启后会在日志中输出请求参数</p>
*/
private boolean isReqParams = false;
/** /**
* 是否自动截断超长参数值(如 base64、大文本 * 是否自动截断超长参数值(如 base64、大文本
* <p>开启后会对超过指定长度的参数值进行截断处理</p> * <p>开启后超过指定长度的参数值将会自动截断处理</p>
*/ */
private boolean truncateLongParams = false; private boolean longParamTruncate = false;
/** /**
* 超长参数检测阈值(单位:字符) * 超长参数检测阈值(单位:字符)
* <p>当参数值长度超过此值时,触发截断规则</p> * <p>当参数值长度超过此值时,触发截断规则</p>
* <p>默认2000</p> * <p>默认2000,仅在 {@link #longParamTruncate} 启用时生效</p>
*/ */
private int ultraLongParamThreshold = 2000; private int longParamThreshold = 2000;
/** /**
* 超长参数最大展示长度(单位:字符) * 超长参数最大保留长度(单位:字符)
* <p>当参数超过ultraLongParamThreshold时强制截断到此长度</p> * <p>当参数超过 {@link #longParamThreshold} 时,强制截断到此长度</p>
* <p>默认50</p> * <p>默认50,仅在 {@link #longParamTruncate} 启用时生效</p>
*/ */
private int ultraLongParamMaxLength = 50; private int longParamMaxLength = 50;
/** /**
* 截断后追加的后缀符号(如配置 "..." 会让截断内容更直观) * 截断后追加的后缀符号(如配置 "..." 会让截断内容更直观)
* <p>建议配置 3-5 个非占宽字符,默认为空不追加</p> * <p>建议配置 3-5 个非占宽字符,默认为 ...</p>
* <p>仅在 {@link #longParamTruncate} 启用时生效</p>
*/ */
private String truncateSuffix = "..."; private String longParamSuffix = "...";
/** /**
* 是否过滤敏感参数 * 是否过滤敏感参数
* <p>开启后会对敏感参数进行过滤,默认不过滤</p> * <p>开启后会对敏感参数进行过滤,默认不过滤</p>
*/ */
private boolean isSensitiveParams = false; private boolean isParamSensitive = false;
/** /**
* 敏感参数字段列表password,token,idCard * 敏感参数字段列表password,token,idCard
* <p>支持精确匹配(区分大小写)</p> * <p>支持精确匹配(区分大小写)</p>
* <p>示例值password,oldPassword</p> * <p>示例值password,oldPassword</p>
*/ */
private List<String> sensitiveParamList = new ArrayList<>(); private List<String> sensitiveParams = new ArrayList<>();
public boolean isPrint() { public boolean isPrint() {
return isPrint; return isPrint;
@@ -95,77 +90,59 @@ public class AccessLogProperties {
isPrint = print; isPrint = print;
} }
public List<String> getExcludePatterns() { public boolean isPrintRequestParam() {
return excludePatterns; return isPrintRequestParam;
} }
public void setExcludePatterns(List<String> excludePatterns) { public void setPrintRequestParam(boolean printRequestParam) {
this.excludePatterns = excludePatterns; isPrintRequestParam = printRequestParam;
} }
public boolean isReqParams() { public boolean isLongParamTruncate() {
return isReqParams; return longParamTruncate;
} }
public void setReqParams(boolean reqParams) { public void setLongParamTruncate(boolean longParamTruncate) {
isReqParams = reqParams; this.longParamTruncate = longParamTruncate;
} }
public boolean isTruncateLongParams() { public int getLongParamThreshold() {
return truncateLongParams; return longParamThreshold;
} }
public void setTruncateLongParams(boolean truncateLongParams) { public void setLongParamThreshold(int longParamThreshold) {
this.truncateLongParams = truncateLongParams; this.longParamThreshold = longParamThreshold;
} }
public int getUltraLongParamThreshold() { public int getLongParamMaxLength() {
return ultraLongParamThreshold; return longParamMaxLength;
} }
public void setUltraLongParamThreshold(int ultraLongParamThreshold) { public void setLongParamMaxLength(int longParamMaxLength) {
this.ultraLongParamThreshold = ultraLongParamThreshold; this.longParamMaxLength = longParamMaxLength;
} }
public int getUltraLongParamMaxLength() { public String getLongParamSuffix() {
return ultraLongParamMaxLength; return longParamSuffix;
} }
public void setUltraLongParamMaxLength(int ultraLongParamMaxLength) { public void setLongParamSuffix(String longParamSuffix) {
this.ultraLongParamMaxLength = ultraLongParamMaxLength; this.longParamSuffix = longParamSuffix;
} }
public String getTruncateSuffix() { public boolean isParamSensitive() {
return truncateSuffix; return isParamSensitive;
} }
public void setTruncateSuffix(String truncateSuffix) { public void setParamSensitive(boolean paramSensitive) {
this.truncateSuffix = truncateSuffix; isParamSensitive = paramSensitive;
} }
public boolean isSensitiveParams() { public List<String> getSensitiveParams() {
return isSensitiveParams; return sensitiveParams;
} }
public void setSensitiveParams(boolean sensitiveParams) { public void setSensitiveParams(List<String> sensitiveParams) {
isSensitiveParams = sensitiveParams; this.sensitiveParams = sensitiveParams;
}
public List<String> getSensitiveParamList() {
return sensitiveParamList;
}
public void setSensitiveParamList(List<String> sensitiveParamList) {
this.sensitiveParamList = sensitiveParamList;
}
/**
* 是否匹配放行路由
*
* @param uri 请求 URI
* @return 是否匹配
*/
public boolean isMatch(String uri) {
return this.getExcludePatterns().stream().anyMatch(pattern -> SpringWebUtils.isMatch(uri, pattern));
} }
} }

View File

@@ -26,14 +26,14 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* 访问日志工具类
*
* @author echo * @author echo
* @since 2025/03/25 19:16 * @author Charles7c
**/ * @since 2.10.0
*/
public class AccessLogUtils { public class AccessLogUtils {
public AccessLogUtils() {
}
/** /**
* 获取参数信息 * 获取参数信息
* *
@@ -42,8 +42,8 @@ public class AccessLogUtils {
* @return {@link String } * @return {@link String }
*/ */
public static String getParam(RecordableHttpRequest request, AccessLogProperties properties) { public static String getParam(RecordableHttpRequest request, AccessLogProperties properties) {
// 是否需要输出参数 // 是否需要打印请求参数
if (!properties.isReqParams()) { if (!properties.isPrintRequestParam()) {
return null; return null;
} }
@@ -54,16 +54,16 @@ public class AccessLogUtils {
} }
// 是否需要对特定入参脱敏 // 是否需要对特定入参脱敏
if (properties.isSensitiveParams()) { if (properties.isParamSensitive()) {
params = filterSensitiveParams(params, properties.getSensitiveParamList()); params = filterSensitiveParams(params, properties.getSensitiveParams());
} }
// 是否自动截断超长参数值 // 是否自动截断超长参数值
if (properties.isTruncateLongParams()) { if (properties.isLongParamTruncate()) {
params = truncateLongParams(params, properties.getUltraLongParamThreshold(), properties params = truncateLongParams(params, properties.getLongParamThreshold(), properties
.getUltraLongParamMaxLength(), properties.getTruncateSuffix()); .getLongParamMaxLength(), properties.getLongParamSuffix());
} }
return "param:" + JSONUtil.toJsonStr(params); return JSONUtil.toJsonStr(params);
} }
/** /**
@@ -80,9 +80,7 @@ public class AccessLogUtils {
Map<String, Object> filteredParams = new HashMap<>(params); Map<String, Object> filteredParams = new HashMap<>(params);
for (String sensitiveKey : sensitiveParams) { for (String sensitiveKey : sensitiveParams) {
if (filteredParams.containsKey(sensitiveKey)) { filteredParams.computeIfPresent(sensitiveKey, (key, value) -> "***");
filteredParams.put(sensitiveKey, "***");
}
} }
return filteredParams; return filteredParams;
} }
@@ -115,4 +113,7 @@ public class AccessLogUtils {
} }
return truncatedParams; return truncatedParams;
} }
private AccessLogUtils() {
}
} }

View File

@@ -64,7 +64,7 @@ public class LogInterceptor implements HandlerInterceptor {
@NonNull HttpServletResponse response, @NonNull HttpServletResponse response,
@NonNull Object handler) { @NonNull Object handler) {
Instant startTime = Instant.now(); Instant startTime = Instant.now();
logHandler.processAccessLogStartReq(AccessLogContext.builder() logHandler.accessLogStart(AccessLogContext.builder()
.startTime(startTime) .startTime(startTime)
.request(new RecordableServletHttpRequest(request)) .request(new RecordableServletHttpRequest(request))
.properties(logProperties) .properties(logProperties)
@@ -84,7 +84,7 @@ public class LogInterceptor implements HandlerInterceptor {
Exception e) { Exception e) {
try { try {
Instant endTime = Instant.now(); Instant endTime = Instant.now();
logHandler.processAccessLogEndReq(AccessLogContext.builder() logHandler.accessLogFinish(AccessLogContext.builder()
.endTime(endTime) .endTime(endTime)
.response(new RecordableServletHttpResponse(response, response.getStatus())) .response(new RecordableServletHttpResponse(response, response.getStatus()))
.build()); .build());