Spring AOP拦截记录日志

自定义注解

@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());
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值