MDC
使用
MDC.put(key, val)
写入需要打印的参数。MDC.clear(); 进行日志的清理
案例
可以记录每次请求的参数、时间、url、token、响应时间
注意:由于每次打印日志很多,建议在开发和测试时候使用,生产环境关闭
package com.xihongshi.common.interceptor;
import com.xihongshi.common.constants.LogConstant;
import com.xihongshi.utils.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @Description: Controller LOG AOP
*/
@Slf4j
@Aspect
public class ApiLogAspect {
@Value("${api.log.enabled:true}")
private boolean enabled = true;
@Value("${api.log.logReqEnabled:true}")
private boolean logReqEnabled = true;
@Value("${api.log.logReqParamEnabled:true}")
private boolean logReqParamEnabled = true;
@Value("${api.log.logRespEnabled:true}")
private boolean logRespEnabled = true;
@Value("${api.log.logRespResultEnabled:true}")
private boolean logRespResultEnabled = true;
@Value("${api.log.printRespResultLimit:1024}")
private Integer printRespResultLimit = 1024;
@Value("${api.log.respCostTimeLimit:1000}")
private Long respCostTimeLimit = 1000L;
@Value("${api.log.logTokenEnabled:true}")
private boolean logTokenEnabled = true;
@Value("${api.log.reqeust.tokenName:token}")
private String tokenName = "token";
public ApiLogAspect() {
log.info("[Api接口日志切面]初始化{}", this);
}
@Pointcut("@within(org.springframework.web.bind.annotation.RestController) && execution(public * com..controller..*.*(..))")
public void controllerPointcut() {
}
@Around("controllerPointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
String traceId = null;
String requestUri = null;
String requestUrl = null;
String clientIp = null;
String token = null;
String param = null;
Long startTime = 0L;
if (isEnabled()) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
startTime = (Long) request.getAttribute(LogConstant.REQUEST_START_TIME_ATTR);
startTime = (null == startTime ? System.currentTimeMillis() : startTime);
traceId = getRequestTraceId(request);
requestUrl = request.getRequestURL().toString();
requestUri = request.getRequestURI();
clientIp = IpUtil.getClientIp(request);
token = isLogTokenEnabled() ? request.getHeader(tokenName) : null;
param = getParams(joinPoint);
MDC.put(LogConstant.LOG_MDC_REQUEST_URI, requestUri);
if (StringUtils.isNotEmpty(traceId)) {
MDC.put(getRequestTraceFlagName(), traceId);
}
//logReuqest
if (isLogReqEnabled()) {
StringBuilder logReuqest = new StringBuilder("logRequest -> token={} ,clientIp={} ,url={}");
List<Object> logParams = new ArrayList(Arrays.asList(new Object[]{token, clientIp, requestUri}));
if (isLogReqParamEnabled()) {
logReuqest.append(" ,param={}");
logParams.add(param);
}
log.info(logReuqest.toString(), logParams.toArray(new Object[]{}));
}
}
Object obj = joinPoint.proceed();
if (isEnabled()) {
long costTime = (System.currentTimeMillis() - startTime);
//logResponse
if (isLogRespEnabled()) {
StringBuilder logResponse = new StringBuilder("logResponse -> token={} ,clientIp={} ,url={} ,costTime={} ,{}={}");
List<Object> logParams = new ArrayList(Arrays.asList(new Object[]{token, clientIp, requestUrl, costTime, getRequestTraceFlagName(), traceId}));
if (isLogReqParamEnabled()) {
logResponse.append(" ,param={}");
logParams.add(param);
}
if (isLogRespResultEnabled()) {
String respStr = obj == null ? "" : obj.toString();
if (null != getPrintRespResultLimit() && getPrintRespResultLimit() > 0 && respStr.length() > getPrintRespResultLimit()) {
respStr = respStr.substring(0, getPrintRespResultLimit());
}
logResponse.append(" -> respStr={}");
logParams.add(respStr);
}
log.info(logResponse.toString(), logParams.toArray(new Object[]{}));
}
//costTimeLong
if (costTime > getRespCostTimeLimit()) {
MDC.put(LogConstant.LOG_RESPONSE_COST_TIME, String.valueOf(costTime));
log.warn("costTimeLong -> clientIp={} ,url={} ,costTime={} ,{}={} ,param={}", clientIp, requestUrl, costTime, getRequestTraceFlagName(), traceId, param);
}
}
return obj;
}
private String getParams(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
if (null != args && args.length > 0) {
List<Object> argList = new ArrayList<>(args.length);
for (Object arg : args) {
if (arg instanceof HttpServletRequest || arg instanceof HttpServletResponse) {
continue;
}
argList.add(arg);
}
return argList.toString();
}
return null;
}
protected String getRequestTraceId(HttpServletRequest request) {
return request.getHeader(getRequestTraceFlagName());
}
protected String getRequestTraceFlagName() {
return LogConstant.REQUEST_HEADER_TRACEID;
}
public boolean isEnabled() {
return enabled;
}
public boolean isLogReqEnabled() {
return logReqEnabled;
}
public boolean isLogReqParamEnabled() {
return logReqParamEnabled;
}
public boolean isLogRespEnabled() {
return logRespEnabled;
}
public boolean isLogRespResultEnabled() {
return logRespResultEnabled;
}
public Integer getPrintRespResultLimit() {
return printRespResultLimit;
}
public long getRespCostTimeLimit() {
return respCostTimeLimit;
}
public boolean isLogTokenEnabled() {
return logTokenEnabled;
}
}