package com.highdatas.mdm.util;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import lombok.Data;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.io.IOUtils;
|
import org.springframework.core.Ordered;
|
import org.springframework.http.HttpStatus;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.util.ContentCachingRequestWrapper;
|
import org.springframework.web.util.ContentCachingResponseWrapper;
|
import org.springframework.web.util.WebUtils;
|
|
import javax.servlet.FilterChain;
|
import javax.servlet.ServletException;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
import java.net.URI;
|
import java.net.URISyntaxException;
|
import java.nio.charset.StandardCharsets;
|
import java.time.LocalDateTime;
|
import java.util.Objects;
|
|
/**
|
* @author kimi
|
* @description
|
* @date 2020-03-17 18:53
|
*/
|
|
@Slf4j
|
public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered {
|
|
private static final String UNNEED_TRACE_PATH_PREFIX = "/file";
|
private static final String IGNORE_CONTENT_TYPE = "multipart/form-data";
|
|
|
|
@Override
|
public int getOrder() {
|
return Ordered.LOWEST_PRECEDENCE - 10;
|
}
|
|
@Override
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
throws ServletException, IOException {
|
if (!isRequestValid(request)) {
|
filterChain.doFilter(request, response);
|
return;
|
}
|
if (!(request instanceof ContentCachingRequestWrapper)) {
|
request = new ContentCachingRequestWrapper(request);
|
}
|
if (!(response instanceof ContentCachingResponseWrapper)) {
|
response = new ContentCachingResponseWrapper(response);
|
}
|
int status = HttpStatus.INTERNAL_SERVER_ERROR.value();
|
long startTime = System.currentTimeMillis();
|
try {
|
filterChain.doFilter(request, response);
|
status = response.getStatus();
|
} finally {
|
String path = request.getRequestURI();
|
boolean isFilterPath = path.startsWith(UNNEED_TRACE_PATH_PREFIX);
|
isFilterPath = true;
|
if (!isFilterPath) {
|
String requestBody = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8.name());
|
log.info(requestBody);
|
//1. 记录日志
|
HttpTraceLog traceLog = new HttpTraceLog();
|
traceLog.setPath(path);
|
traceLog.setMethod(request.getMethod());
|
long latency = System.currentTimeMillis() - startTime;
|
traceLog.setTimeTaken(latency);
|
traceLog.setTime(LocalDateTime.now().toString());
|
traceLog.setParameterMap(JSON.toJSONString(request.getParameterMap()));
|
traceLog.setStatus(status);
|
traceLog.setUserIp( request.getRemoteAddr());
|
traceLog.setRequestBody(getRequestBody(request));
|
String responseBody = getResponseBody(response);
|
try{
|
JSONObject jsonObject = JSONObject.parseObject(responseBody);
|
if (jsonObject != null){
|
traceLog.setResponseStatus(jsonObject.getString("success"));
|
}
|
}
|
catch (Exception e){
|
e.printStackTrace();
|
}
|
|
// traceLog.setResponseBody(responseBody);
|
log.info("Http trace log: {}", JSON.toJSONString(traceLog));
|
}
|
updateResponse(response);
|
}
|
}
|
|
private boolean isRequestValid(HttpServletRequest request) {
|
try {
|
new URI(request.getRequestURL().toString());
|
return true;
|
} catch (URISyntaxException ex) {
|
return false;
|
}
|
}
|
|
private String getRequestBody(HttpServletRequest request) {
|
String requestBody = "";
|
ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
|
if (wrapper != null) {
|
try {
|
requestBody = IOUtils.toString(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding());
|
} catch (IOException e) {
|
// NOOP
|
}
|
}
|
return requestBody;
|
}
|
|
private String getResponseBody(HttpServletResponse response) {
|
String responseBody = "";
|
ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
|
if (wrapper != null) {
|
try {
|
responseBody = IOUtils.toString(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding());
|
} catch (IOException e) {
|
// NOOP
|
}
|
}
|
return responseBody;
|
}
|
|
private void updateResponse(HttpServletResponse response) throws IOException {
|
ContentCachingResponseWrapper responseWrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
|
Objects.requireNonNull(responseWrapper).copyBodyToResponse();
|
}
|
|
|
@Data
|
public static class HttpTraceLog {
|
private String path;
|
private String parameterMap;
|
private String method;
|
private Long timeTaken;
|
private String time;
|
private Integer status;
|
private String requestBody;
|
private String userId;
|
private String userIp;
|
private String urlId;
|
private String responseStatus;
|
}
|
}
|