优化http请求日志记录
This commit is contained in:
@@ -9,11 +9,11 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import org.jspecify.annotations.NonNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StopWatch;
|
||||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||||
import xtools.app.common.log.whitelist.HttpLogWhitelist;
|
import xtools.app.common.log.whitelist.HttpLogWhitelist;
|
||||||
import xtools.base.config.BaseParams;
|
import xtools.base.config.BaseParams;
|
||||||
import xtools.boot.api.constant.BootCommonConstant;
|
|
||||||
import xtools.boot.api.model.dto.log.LogTrack;
|
import xtools.boot.api.model.dto.log.LogTrack;
|
||||||
import xtools.boot.core.utils.PathPatternUtils;
|
import xtools.boot.core.utils.PathPatternUtils;
|
||||||
import xtools.boot.core.utils.SpringContextUtils;
|
import xtools.boot.core.utils.SpringContextUtils;
|
||||||
@@ -30,6 +30,7 @@ import xtools.web.HeaderUtils;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -93,13 +94,20 @@ public class HttpLogFilter extends BaseFilter implements Ordered, BaseParams {
|
|||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 开始时间
|
// 开始计时
|
||||||
long startTime = System.currentTimeMillis();
|
StopWatch sw = new StopWatch();
|
||||||
|
sw.start();
|
||||||
|
|
||||||
// 获取请求日志
|
// 获取请求日志
|
||||||
JSONObject log = getRequestLog(request);
|
JSONObject requestLog = getRequestLog(request);
|
||||||
// 记录请求日志
|
|
||||||
saveLog(LogBusBaseType.HTTP_REQUEST, log);
|
// 获取所有请求头信息
|
||||||
|
JSONObject requestHeaders = getRequestHeaders(request);
|
||||||
|
requestLog.put("headers", requestHeaders);
|
||||||
|
|
||||||
|
// 获取请求日志节点
|
||||||
|
LogTrack logTrack = LogTrackHolder.get();
|
||||||
|
|
||||||
// 包装请求和响应
|
// 包装请求和响应
|
||||||
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request, DEFAULT_CACHE_LIMIT);
|
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request, DEFAULT_CACHE_LIMIT);
|
||||||
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
|
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
|
||||||
@@ -107,26 +115,64 @@ public class HttpLogFilter extends BaseFilter implements Ordered, BaseParams {
|
|||||||
// 处理请求
|
// 处理请求
|
||||||
filterChain.doFilter(requestWrapper, responseWrapper);
|
filterChain.doFilter(requestWrapper, responseWrapper);
|
||||||
|
|
||||||
// 获取请求参数
|
// 获取请求体数据
|
||||||
Object reqParam = getContent(requestWrapper.getContentAsByteArray());
|
requestLog.put("requestBody", getContent(requestWrapper.getContentAsByteArray()));
|
||||||
|
// 记录请求日志
|
||||||
|
saveLog(logTrack, LogBusBaseType.HTTP_REQUEST, requestLog);
|
||||||
|
|
||||||
|
// 获取响应头信息
|
||||||
|
JSONObject responseHeaders = getResponseHeaders(responseWrapper);
|
||||||
|
// 获取响应体数据
|
||||||
Object respData;
|
Object respData;
|
||||||
if (!PathPatternUtils.match(RESP_WHITE_LIST, uri)) {
|
if (PathPatternUtils.match(RESP_WHITE_LIST, uri)) {
|
||||||
|
respData = "ignore";
|
||||||
|
} else {
|
||||||
// 获取响应内容
|
// 获取响应内容
|
||||||
respData = getContent(responseWrapper.getContentAsByteArray());
|
respData = getContent(responseWrapper.getContentAsByteArray());
|
||||||
} else {
|
|
||||||
respData = "ignore";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将内容复制回原始响应
|
// 将内容复制回原始响应
|
||||||
responseWrapper.copyBodyToResponse();
|
responseWrapper.copyBodyToResponse();
|
||||||
|
|
||||||
// 保存日志
|
// 停止计时
|
||||||
log.put("reqBody", reqParam);
|
sw.stop();
|
||||||
log.put("respData", respData);
|
|
||||||
log.put("execTime", System.currentTimeMillis() - startTime);
|
|
||||||
|
|
||||||
// 记录响应日志
|
// 保存日志
|
||||||
saveLog(LogBusBaseType.HTTP_RESPONSE, log);
|
JSONObject responseLog = JSONObject.of(
|
||||||
|
"headers", responseHeaders,
|
||||||
|
"responseBody", respData,
|
||||||
|
"execTime", sw.getTotalTimeMillis()
|
||||||
|
);
|
||||||
|
saveLog(LogTrackHolder.get(), LogBusBaseType.HTTP_RESPONSE, responseLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取请求头信息
|
||||||
|
*
|
||||||
|
* @param request 请求
|
||||||
|
* @return 请求头信息
|
||||||
|
*/
|
||||||
|
private JSONObject getRequestHeaders(HttpServletRequest request) {
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
Enumeration<String> headerNames = request.getHeaderNames();
|
||||||
|
while (headerNames.hasMoreElements()) {
|
||||||
|
String headerName = headerNames.nextElement();
|
||||||
|
headers.put(headerName, request.getHeader(headerName));
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取响应头信息
|
||||||
|
*
|
||||||
|
* @param response 响应
|
||||||
|
* @return 响应头信息
|
||||||
|
*/
|
||||||
|
private JSONObject getResponseHeaders(HttpServletResponse response) {
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
Collection<String> headerNames = response.getHeaderNames();
|
||||||
|
headerNames.forEach(headerName -> headers.put(headerName, response.getHeader(headerName)));
|
||||||
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -167,23 +213,19 @@ public class HttpLogFilter extends BaseFilter implements Ordered, BaseParams {
|
|||||||
log.put("method", request.getMethod());
|
log.put("method", request.getMethod());
|
||||||
log.put("query", HeaderUtils.getQuery(request));
|
log.put("query", HeaderUtils.getQuery(request));
|
||||||
log.put("params", HeaderUtils.getParamsToString(request));
|
log.put("params", HeaderUtils.getParamsToString(request));
|
||||||
log.put("userAgent", HeaderUtils.getUserAgent(request));
|
|
||||||
log.put("referer", HeaderUtils.getReferer(request));
|
|
||||||
log.put("ip", HeaderUtils.getIp(request));
|
log.put("ip", HeaderUtils.getIp(request));
|
||||||
log.put(BootCommonConstant.UID, HeaderUtils.getRequestParam(request, BootCommonConstant.UID));
|
|
||||||
log.put(BootCommonConstant.AUTHORIZATION, HeaderUtils.getRequestParam(request, BootCommonConstant.AUTHORIZATION));
|
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存日志
|
* 保存日志
|
||||||
*
|
*
|
||||||
|
* @param logTrack 日志追踪信息
|
||||||
* @param type 日志类型
|
* @param type 日志类型
|
||||||
* @param log 日志
|
* @param log 日志
|
||||||
*/
|
*/
|
||||||
private void saveLog(LogBusType type, Object log) {
|
private void saveLog(LogTrack logTrack, LogBusType type, Object log) {
|
||||||
LogTrack track = LogTrackHolder.get();
|
VirtualThreadTaskUtils.simple(() -> LogBus.init(LogLevel.INFO, type, logTrack).data(log).save());
|
||||||
VirtualThreadTaskUtils.simple(() -> LogBus.init(LogLevel.INFO, type, track).data(log).save());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user