项目AOP处理请求日志

项目AOP处理请求日志

单个请求

功能描述:在进入请求前打印日志及参数,请求执行完成后打印响应结果。
为要打印日志的请求定义注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLog {
    /**
     * 请求名称
     *
     * @return /
     */
    String value() default "";
}

使用AOP解析每个使用了该注解的请求:

@Slf4j
@Aspect
@Component
public class RequestLogResolver {

    @Pointcut("@annotation(com.xxx.xxx.common.aspect.RequestLog)")
    private void pointCut() {
    }

    @Around("pointCut()")
    public Object beforeRequestLog(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        Annotation[] annotations = method.getAnnotations();
        RequestLog requestLogAnnotation = null;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType().getSimpleName().equals(RequestLog.class.getSimpleName())) {
                requestLogAnnotation = (RequestLog) annotation;
                break;
            }
        }
        String requestName = "";
        if (requestLogAnnotation != null) {
            requestName = requestLogAnnotation.value();
        }
        StringBuilder parameterPlaceHolder = new StringBuilder();
        Object[] args = pjp.getArgs();
        int length = args.length;
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                parameterPlaceHolder.append("参数 ").append(i + 1).append(":{}  ");
            }
            log.info("开始执行【" + requestName + "】请求,请求参数为:" + parameterPlaceHolder, args);
        } else {
            log.info("开始执行【" + requestName + "】请求,请求参数为空");
        }
        Object result = pjp.proceed(args);
        log.info("结束执行【" + requestName + "】请求,请求结果为:{}", result);
        return result;
    }

}

微服务关联请求

(下面代码是基于Feign写的,服务间调用采用其它方式的可以参考下面的写法)
功能描述:在进入请求前打印请求参数,如果整个请求内有访问其它服务,其它服务会基于同一个请求ID,打印日志,请求结束后打印响应结果。服务内所有请求都有同一个请求ID,便于定位问题。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLog {
    /**
     * 请求名称
     *
     * @return /
     */
    String value() default "";

    /**
     * 是否继承RequestId
     * 默认继承
     *
     * @return /
     */
    boolean extendsRequestId() default true;
}

@Slf4j
@Aspect
@Component
public class RequestLogResolver {

    public static final String REQUEST_LOG_ID_NAME = "NEW_COIN_REQUEST_LOG_ID";

    @Pointcut("@annotation(com.xxx.common.web.aspect.RequestLog)")
    private void pointCut() {
    }

    @Around("pointCut()")
    public Object beforeRequestLog(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        Annotation[] annotations = method.getAnnotations();
        RequestLog requestLogAnnotation = null;
        for (Annotation annotation : annotations) {
            if (annotation.annotationType().getSimpleName().equals(RequestLog.class.getSimpleName())) {
                requestLogAnnotation = (RequestLog) annotation;
                break;
            }
        }
        String requestName = "";
        boolean extendsRequestId = true;
        if (requestLogAnnotation != null) {
            requestName = requestLogAnnotation.value();
            extendsRequestId = requestLogAnnotation.extendsRequestId();
        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        String requestId = null;
        if (extendsRequestId) {
            // 继承RequestId,从Header中取值
            requestId =  request.getHeader(REQUEST_LOG_ID_NAME);
        }

        if (requestId == null) {
            requestId = "REQUEST_" + UUIDUtils.uuid();
        }
        HttpSession session = request.getSession();
        session.setAttribute(REQUEST_LOG_ID_NAME, requestId);

        StringBuilder parameterPlaceHolder = new StringBuilder();
        Object[] args = pjp.getArgs();
        int length = args.length;
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                parameterPlaceHolder.append("参数 ").append(i + 1).append(":{}  ");
            }
            log.info("开始执行【" + requestName + "】请求【{}】,请求参数为:" + parameterPlaceHolder, requestId, args);
        } else {
            log.info("开始执行【" + requestName + "】请求【{}】,请求参数为空");
        }
        Object result = pjp.proceed(args);
        log.info("结束执行【" + requestName + "】请求【{}】,请求结果为:{}", requestId, result);
        // 请求结束后,清除请求ID
        session.removeAttribute(REQUEST_LOG_ID_NAME);
        return result;
    }

}
@Slf4j
@Configuration
public class FeignConfiguration implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpSession session = attributes.getRequest().getSession();
        String requestId = (String) session.getAttribute(RequestLogResolver.REQUEST_LOG_ID_NAME);
        if (StringUtils.isNotEmpty(requestId)) {
            log.debug("Feign调用设置请求ID,{}", requestId);
            requestTemplate.header(RequestLogResolver.REQUEST_LOG_ID_NAME, requestId);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值