package com.xxx.xxx.filter;
import com.xxx.xxx.util.CommonUtils;
import com.xxx.xxx.util.RequestUtils;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.ThreadContext;
import org.springframework.http.HttpMethod;
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.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
-
@author langhsu on 2015/7/10.
-
https://github.com/xukh630/jcs
*/
@Slf4j
public class TraceLogFilter extends OncePerRequestFilter {
private static final Set EXCLUDE_URI = new HashSet<>(32);
private static final Set SENSITIVITY_URI = new HashSet<>(16);static {
// EXCLUDE_URI.add("/dist");
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
long startTime = System.currentTimeMillis();
if (!(request instanceof ContentCachingRequestWrapper)) {
request = new ContentCachingRequestWrapper(request);
}
if (!(response instanceof ContentCachingResponseWrapper)) {
response = new ContentCachingResponseWrapper(response);
}
int status = HttpStatus.INTERNAL_SERVER_ERROR.value();
String uri = request.getRequestURI();
ThreadContext.put("logid", CommonUtils.getLogId());
try {
chain.doFilter(request, response);
} catch (Exception e) {
log.error("request " + uri , e);
}
String responseBody = getResponseBody(response);
status = response.getStatus();
if (isPrintLog(uri)) {
// String ip = RequestUtils.getRealIP(request);
String url = request.getRequestURL().toString();
// String method = request.getMethod();
long usedTime = System.currentTimeMillis() - startTime;
String header = "header";
String param = null;
try {
param = getRequestBody(request);
if (isSensitivityUri(request.getRequestURI())) {
header = RequestUtils.getHeadersJson(request);
}
} catch (Exception e) {
log.error("", e);
}
// String ret = getResponseBody(responseWrapper);
TraceLog traceLog = TraceLog.builder()
// .ip(ip) //todo 无意义,都是nginx 本机
.url(url.substring(22))
// .method(method)
.usedTime(usedTime)
.status(status)
.header(header)
.param(param)
.responseBody(responseBody)
.build();
log.info(traceLog.toString());
}
updateResponse(response);
ThreadContext.clearAll();
}
private String getRequestBody(HttpServletRequest request) throws Exception {
ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
//return new String(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding());
return getRequestString(wrapper);
}
private String getRequestString(ContentCachingRequestWrapper request) {
String payload = "{}";
if (request != null) {
if (request.getMethod().equalsIgnoreCase(HttpMethod.POST.name())) {
byte[] buf = request.getContentAsByteArray();
if (buf.length > 0 && buf.length < 1024 * 64) {
try {
payload = new String(buf, 0, buf.length, request.getCharacterEncoding());
} catch (UnsupportedEncodingException ex) {
payload = "[unknown]";
}
} else if (buf.length >= 1024 * 64) {
return String.format("[too long content, length = %s]", buf.length);
}
} else {
payload = request.getQueryString() == null ? "{}" : request.getQueryString();
}
}
return payload;
}
private String getResponseBody(HttpServletResponse response) {
ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
if (null != wrapper) {
try {
return new String(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding());
} catch (IOException e) {
log.error("getResponseBody Exception >>> ", e);
}
}
return "";
}
private void updateResponse(HttpServletResponse response) throws IOException {
ContentCachingResponseWrapper responseWrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
Objects.requireNonNull(responseWrapper).copyBodyToResponse();
}
// private String getResponseBody(ContentCachingResponseWrapper response) {
// ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
// if (wrapper != null) {
// byte[] buf = wrapper.getContentAsByteArray();
// if (buf.length > 0) {
// String payload;
// try {
// payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding());
// } catch (UnsupportedEncodingException e) {
// payload = "[unknown]";
// }
// return payload;
// }
// }
// return "";
// }
private static boolean isSensitivityUri(String uri) {
boolean result = true;
for (String suri : SENSITIVITY_URI) {
if (uri.equals(suri)) {
result = false;
break;
}
}
return result;
}
private static boolean isPrintLog(String uri) {
boolean result = true;
for (String euri : EXCLUDE_URI) {
if (uri.startsWith(euri)) {
result = false;
break;
}
}
return result;
}
@Builder
private final static class TraceLog {
private String ip;
private String url;
private String method;
private Long usedTime;
private Integer status;
private String header;
private String param;
private String responseBody;
@Override
public String toString() {
return
// "|" + ip +
"|'" + url +
// "'|" + method +
"'|" + status +
"|" + usedTime +
"|" + param +
"|" + header +
"|" + responseBody ;
}
}
}
对应log4j2