添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
AOP 代码:
package com.gtcom.api.aspect;
import com.alibaba.fastjson.JSON;
import com.gtcom.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.stereotype.Component;
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.HashMap;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* com.gtcom.api.controller..*.*(..))")
public void pointCut() {
}
@Pointcut("execution(* com.gtcom.api.exception..*.*(..))")
public void exceptionPointCut() {
}
@Before(value = "pointCut()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (Objects.isNull(servletRequestAttributes)) {
return;
}
HttpServletRequest request = servletRequestAttributes.getRequest();
String ip = request.getRemoteAddr();
String method = request.getMethod();
String uri = request.getRequestURI();
log.info("[请求接口] - {} : {} : {}", ip, method, uri);
if (log.isDebugEnabled()) {
Object[] parameterValues = joinPoint.getArgs();
int parameterValuesLength = parameterValues.length;
if (parameterValuesLength == Constants.ZERO) {
log.debug("[请求参数] - 无");
return;
}
Signature signature = joinPoint.getSignature();
if (Objects.isNull(signature)) {
return;
}
String[] parameterNames = ((CodeSignature) signature).getParameterNames();
if (Objects.isNull(parameterNames) || parameterNames.length != parameterValuesLength) {
return;
}
Map<String, Object> params = new HashMap<>(Constants.TWO);
for (int i = Constants.ZERO; i < parameterNames.length; i++) {
params.put(parameterNames[i], parameterValues[i]);
}
log.debug("[请求参数] - {}", JSON.toJSONString(params));
}
}
@AfterReturning(returning = "result", pointcut = "pointCut() || exceptionPointCut()")
public void doAfterReturning(Object result) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (Objects.isNull(servletRequestAttributes)) {
return;
}
HttpServletResponse response = servletRequestAttributes.getResponse();
if (Objects.isNull(response)) {
return;
}
int status = response.getStatus();
HttpServletRequest request = servletRequestAttributes.getRequest();
String method = request.getMethod();
String uri = request.getRequestURI();
log.info("[响应结果] - {} : {} : {}", status, method, uri);
if (log.isDebugEnabled()) {
log.debug("[响应内容] - {}", JSON.toJSONString(result));
}
}
}
打印日志:
2021-11-10 19:18:49.762 - INFO [b79971ff62ee43dd8470a4be9e602f61] 11828 --- [nio-8082-exec-1] com.gtcom.api.aspect.LogAspect : [请求接口] - 0:0:0:0:0:0:0:1 : GET : /api/test
2021-11-10 19:18:49.763 -DEBUG [b79971ff62ee43dd8470a4be9e602f61] 11828 --- [nio-8082-exec-1] com.gtcom.api.aspect.LogAspect : [请求参数] - 无
2021-11-10 19:18:49.767 - INFO [b79971ff62ee43dd8470a4be9e602f61] 11828 --- [nio-8082-exec-1] com.gtcom.api.controller.TestController : =================测试接口================
2021-11-10 19:18:49.768 - INFO [b79971ff62ee43dd8470a4be9e602f61] 11828 --- [nio-8082-exec-1] com.gtcom.api.aspect.LogAspect : [响应结果] - 200 : GET : /api/test
2021-11-10 19:18:49.845 -DEBUG [b79971ff62ee43dd8470a4be9e602f61] 11828 --- [nio-8082-exec-1] com.gtcom.api.aspect.LogAspect : [响应内容] - {"code":20000,"message":"成功"}
这里添加了简单的 MDC:
server.servlet.context-path=/api
logging.pattern.console=%clr(%d{${LOG_DATEFORMAT_PATTERN:yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%X{trace_id}]) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}
package com.gtcom.api.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
/**
* MDC拦截器
*
* @author wangbo
* @date 2021/10/27
*/
@Slf4j
@Component
public class MdcInterceptor implements HandlerInterceptor {
private final static String TRACE_ID = "trace_id";
@Override
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
MDC.put(TRACE_ID, UUID.randomUUID().toString().replace("-", ""));
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, Exception ex) throws Exception {
MDC.remove(TRACE_ID);
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
package com.gtcom.api.config;
import com.gtcom.api.interceptor.MdcInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* WebMvc配置
*
* @author wangbo
* @date 2021/10/27
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final MdcInterceptor mdcInterceptor;
public WebMvcConfig(MdcInterceptor mdcInterceptor) {
this.mdcInterceptor = mdcInterceptor;
}
/**
* 注册拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(mdcInterceptor);
}
}