access log 使用 responseWrapper,记录响应数据

This commit is contained in:
b2baccline
2020-07-16 18:58:24 +08:00
parent b35f4c2dc2
commit 23b56ca278
4 changed files with 49 additions and 6 deletions

View File

@@ -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());

View File

@@ -99,6 +99,12 @@ public class AdminAccessLog extends Model<AdminAccessLog> {
@ApiModelProperty(value = "响应状态码")
private Integer httpStatus;
/**
* 响应信息
*/
@ApiModelProperty(value = "响应信息")
private String result;
/**
* 错误消息
*/

View File

@@ -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();
}
}
}

View File

@@ -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 请求信息