package com.cloudroam.module.log;
|
|
import com.cloudroam.common.util.IPUtil;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.slf4j.MDC;
|
|
import javax.servlet.Filter;
|
import javax.servlet.FilterChain;
|
import javax.servlet.ServletException;
|
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletResponse;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
|
/**
|
* 记录 access log 的过滤器
|
* 会把 request、response 相关信息(如 IP、URL)放入 Logback 的 MDC中
|
*
|
* @author
|
* @date 2020/6/20 09:58
|
*/
|
public class MDCAccessServletFilter implements Filter {
|
|
private static final Logger log = LoggerFactory.getLogger(MDCAccessServletFilter.class);
|
|
@Override
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
putRequestMDC(request);
|
try {
|
chain.doFilter(request, response);
|
putResponseMDC(response);
|
accessLog();
|
} finally {
|
clearMDC();
|
}
|
}
|
|
/**
|
* 记录 access log
|
*/
|
public void accessLog() {
|
log.info("");
|
}
|
|
public void putResponseMDC(ServletResponse servletResponse) {
|
if (servletResponse instanceof HttpServletResponse) {
|
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
|
MDC.put(MDCAccessConstant.RESPONSE_STATUS_MDC_KEY, String.valueOf(httpServletResponse.getStatus()));
|
}
|
}
|
|
/**
|
* 放入 request 信息
|
*/
|
public void putRequestMDC(ServletRequest servletRequest) throws IOException {
|
MDC.put(MDCAccessConstant.REQUEST_REMOTE_HOST_MDC_KEY, servletRequest.getRemoteHost());
|
MDC.put(MDCAccessConstant.REQUEST_PROTOCOL_MDC_KEY, servletRequest.getProtocol());
|
MDC.put(MDCAccessConstant.REQUEST_REMOTE_ADDR_MDC_KEY, servletRequest.getRemoteAddr());
|
MDC.put(MDCAccessConstant.REQUEST_REMOTE_PORT_MDC_KEY, String.valueOf(servletRequest.getRemotePort()));
|
MDC.put(MDCAccessConstant.REQUEST_BODY_BYTES_SENT_MDC_KEY, String.valueOf(servletRequest.getContentLength()));
|
|
if (servletRequest instanceof HttpServletRequest) {
|
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
|
MDC.put(MDCAccessConstant.REQUEST_REMOTE_ADDR_MDC_KEY, IPUtil.getIPFromRequest(httpServletRequest));
|
MDC.put(MDCAccessConstant.REQUEST_REQUEST_URI_MDC_KEY, httpServletRequest.getRequestURI());
|
StringBuffer requestUrl = httpServletRequest.getRequestURL();
|
if (requestUrl != null) {
|
MDC.put(MDCAccessConstant.REQUEST_REQUEST_URL_MDC_KEY, requestUrl.toString());
|
}
|
MDC.put(MDCAccessConstant.REQUEST_METHOD_MDC_KEY, httpServletRequest.getMethod());
|
MDC.put(MDCAccessConstant.REQUEST_QUERY_STRING_MDC_KEY, httpServletRequest.getQueryString());
|
MDC.put(MDCAccessConstant.REQUEST_USER_AGENT_MDC_KEY, httpServletRequest.getHeader("User-Agent"));
|
MDC.put(MDCAccessConstant.REQUEST_X_FORWARDED_FOR_MDC_KEY, httpServletRequest.getHeader("X-Forwarded-For"));
|
MDC.put(MDCAccessConstant.REQUEST_REFERER_MDC_KEY, httpServletRequest.getHeader("referer"));
|
}
|
}
|
|
/**
|
* 清理 MDC,特别重要
|
* 因为 MDC 由 ThreadLocal 实现,如果不清理,线程池的复用机制会导致 MDC 数据受到污染
|
*/
|
public void clearMDC() {
|
MDC.remove(MDCAccessConstant.REQUEST_METHOD_MDC_KEY);
|
MDC.remove(MDCAccessConstant.RESPONSE_STATUS_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_REFERER_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_PROTOCOL_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_USER_AGENT_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_REMOTE_HOST_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_REMOTE_ADDR_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_REQUEST_URI_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_REQUEST_URL_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_QUERY_STRING_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_X_FORWARDED_FOR_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_BODY_BYTES_SENT_MDC_KEY);
|
MDC.remove(MDCAccessConstant.REQUEST_REMOTE_PORT_MDC_KEY);
|
}
|
|
}
|