✨ access log 使用 responseWrapper,记录响应数据
This commit is contained in:
@@ -32,6 +32,8 @@ import java.util.Optional;
|
||||
@RequiredArgsConstructor
|
||||
public class AdminAccessLogHandler implements AccessLogHandler<AdminAccessLog> {
|
||||
|
||||
private final static String APPLICATION_JSON = "application/json";
|
||||
|
||||
private final AccessLogAdminSaveThread accessLogAdminSaveThread;
|
||||
|
||||
/**
|
||||
@@ -65,6 +67,12 @@ public class AdminAccessLogHandler implements AccessLogHandler<AdminAccessLog> {
|
||||
adminAccessLog.setReqBody(LogUtils.getRequestBody(request));
|
||||
}
|
||||
|
||||
// 只记录响应头为 application/json 的返回数据
|
||||
// 后台日志对于分页数据请求,不记录返回值
|
||||
if (!request.getRequestURI().endsWith("/page") && response.getContentType().contains(APPLICATION_JSON)) {
|
||||
adminAccessLog.setResult(LogUtils.getResponseBody(response));
|
||||
}
|
||||
|
||||
// 如果登陆用户 则记录用户名和用户id
|
||||
Optional.ofNullable(SecurityUtils.getSysUserDetails()).map(SysUserDetails::getSysUser).ifPresent(x -> {
|
||||
adminAccessLog.setUserId(x.getUserId());
|
||||
|
||||
@@ -99,6 +99,12 @@ public class AdminAccessLog extends Model<AdminAccessLog> {
|
||||
@ApiModelProperty(value = "响应状态码")
|
||||
private Integer httpStatus;
|
||||
|
||||
/**
|
||||
* 响应信息
|
||||
*/
|
||||
@ApiModelProperty(value = "响应信息")
|
||||
private String result;
|
||||
|
||||
/**
|
||||
* 错误消息
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.hccake.ballcat.common.core.request.wrapper.RepeatBodyRequestWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
@@ -63,12 +64,14 @@ public class AccessLogFilter extends OncePerRequestFilter {
|
||||
else {
|
||||
requestWrapper = new RepeatBodyRequestWrapper(request);
|
||||
}
|
||||
// 包装 response,便于重复获取 body
|
||||
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
|
||||
|
||||
// 开始时间
|
||||
Long startTime = System.currentTimeMillis();
|
||||
Throwable myThrowable = null;
|
||||
try {
|
||||
filterChain.doFilter(requestWrapper, response);
|
||||
filterChain.doFilter(requestWrapper, responseWrapper);
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
// 记录外抛异常
|
||||
@@ -87,9 +90,10 @@ public class AccessLogFilter extends OncePerRequestFilter {
|
||||
myThrowable = throwable;
|
||||
}
|
||||
// 生产一个日志并记录
|
||||
accessLogService.logRecord(requestWrapper, response, executionTime, myThrowable);
|
||||
accessLogService.logRecord(requestWrapper, responseWrapper, executionTime, myThrowable);
|
||||
// 重新写入数据到响应信息中
|
||||
responseWrapper.copyBodyToResponse();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,9 +12,12 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -31,7 +34,7 @@ public class LogUtils {
|
||||
|
||||
/**
|
||||
* 获取当前登陆用户名
|
||||
* @return
|
||||
* @return current login user name
|
||||
*/
|
||||
public String getUsername() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
@@ -43,8 +46,8 @@ public class LogUtils {
|
||||
|
||||
/**
|
||||
* 获取请求体
|
||||
* @param request
|
||||
* @return
|
||||
* @param request 请求体
|
||||
* @return requestBody
|
||||
*/
|
||||
public String getRequestBody(HttpServletRequest request) {
|
||||
String body = null;
|
||||
@@ -62,6 +65,28 @@ public class LogUtils {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取响应体
|
||||
* @param response 响应信息
|
||||
* @return responseBody 响应体
|
||||
*/
|
||||
public String getResponseBody(HttpServletResponse response) {
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
try {
|
||||
if (response instanceof ContentCachingResponseWrapper) {
|
||||
ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response;
|
||||
// 获取响应体
|
||||
byte[] contentAsByteArray = responseWrapper.getContentAsByteArray();
|
||||
return new String(contentAsByteArray, StandardCharsets.UTF_8);
|
||||
}
|
||||
log.warn("对于未包装的响应体,默认不进行读取请求体,请求 uri: [{}]", request.getRequestURI());
|
||||
}
|
||||
catch (Exception exception) {
|
||||
log.error("获取响应体信息失败,请求 uri: [{}]", request.getRequestURI());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是multipart/form-data请求
|
||||
* @param request 请求信息
|
||||
|
||||
Reference in New Issue
Block a user