自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface IgnoreRequestLog {
IgnoreType[] types() default {IgnoreType.REQUEST, IgnoreType.RESPONSE};
enum IgnoreType {
REQUEST,
RESPONSE,
}
}
定义AOP拦截请求
@Slf4j
@Aspect
@Component
public class RequestLogAspect {
private final static Integer MAX_LOG_SIZE = 2048;
private static Set<Class<?>> EXCLUDE_CLASSES = ImmutableSet.of(ServletRequest.class, ServletResponse.class);
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) " +
"|| @annotation(org.springframework.web.bind.annotation.PostMapping) " +
"|| @annotation(org.springframework.web.bind.annotation.GetMapping) ")
public void pointCut() {
}
@Around("pointCut()")
public Object doRequestLog(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
IgnoreRequestLog annotation = AnnotationUtils.findAnnotation(((MethodSignature) joinPoint.getSignature()).getMethod(),
IgnoreRequestLog.class);
Stopwatch stopwatch = Stopwatch.createStarted();
Object proceed;
try {
proceed = joinPoint.proceed(joinPoint.getArgs());
} catch (Exception e) {
log.error("api log, process error, api log, url = {}, params = {}, time cost = {} and throws exception: ",
request.getRequestURI(),
buildRequestLog(joinPoint, annotation),
stopwatch.elapsed(TimeUnit.MILLISECONDS),
e);
throw e;
}
log.info("api log, url = {}, params = {}, result = {}, time cost = {}",
request.getRequestURI(),
buildRequestLog(joinPoint, annotation),
buiResponseLog(proceed, annotation),
stopwatch.elapsed(TimeUnit.MILLISECONDS));
return proceed;
}
private String buildRequestLog(ProceedingJoinPoint joinPoint, IgnoreRequestLog annotation) {
if (annotation != null
&& ImmutableSet.copyOf(annotation.types()).contains(IgnoreRequestLog.IgnoreType.REQUEST)) {
return "IGNORED";
}
return StringUtils.left(SensitiveUtils.toJson(this.getUserArgs(joinPoint.getArgs())), MAX_LOG_SIZE);
}
private String buiResponseLog(Object proceed, IgnoreRequestLog annotation) {
if (proceed == null || !proceed.getClass().isAssignableFrom(Result.class)) {
return StringUtils.EMPTY;
}
if (annotation != null
&& ImmutableSet.copyOf(annotation.types()).contains(IgnoreRequestLog.IgnoreType.RESPONSE)) {
return "IGNORED";
}
return StringUtils.left(SensitiveUtils.toJson(proceed), MAX_LOG_SIZE);
}
protected List<Object> getUserArgs(Object[] args) {
return Arrays.stream(args)
.filter((p) -> Objects.nonNull(p) && EXCLUDE_CLASSES.stream().noneMatch(clz -> clz.isAssignableFrom(p.getClass())))
.collect(Collectors.toList());
}
}