利用SpringAOP做简单的监控日志

本文介绍了如何使用自定义注解@Monitor监控Spring AOP的方法调用,包括注解的定义、AOP切点选择及围绕通知中参数的获取和日志记录。展示了如何通过AOP代理开启,以及获取请求信息并存储潜在的日志服务器功能(尚未实现)。
摘要由CSDN通过智能技术生成

1.自定义日志监控注解,用于触发aop监控

/**
 * 自定义监控注解(标注在方法上,监控基本信息)
 *
 * @author rzx
 */
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Monitor {

    String describe() default "";
}

2.编写AOP监控信息(获取信息后可以做记录存储到日志服务器(未实现))

/**
 * @program: route-forecast
 * @description: 监控信息
 * @author: rzx
 * @create: 2021-06-07 17:32
 **/
@Aspect
@Component
@Slf4j
public class MonitorAop {

    @Pointcut("@annotation(Monitor)")
    public void monitor() {
    }

     @Around("monitor()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        StringBuffer argsType = null;
        Monitor annotation = null;
        Object result = null;
        try {

            /**获取当前请求对象*/
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            /**获取当前请求url*/
            String urlStr = request.getRequestURL().toString();
            /**获取接入点对象*/
            Class<?> targetClassName = joinPoint.getTarget().getClass();
            Signature signature = joinPoint.getSignature();
            /**对象类型*/
            String typeStr = signature.getDeclaringType().toString().split(" ")[0];
            /**获取方法中的注解信息*/
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            annotation = method.getAnnotation(Monitor.class);

            Object[] args = joinPoint.getArgs();
            int length = args.length;

            long begin = System.currentTimeMillis();
            result = joinPoint.proceed();

            long delay = System.currentTimeMillis() - begin;
            log.debug("请求的url: " + urlStr);
            log.debug("请求类/接口名: " + targetClassName.getSimpleName() + "(" + typeStr + ")");
            log.debug("方法名: " + signature.getName());
            if (StringUtils.isNotBlank(annotation.describe())) {
                log.debug("方法监控描述: " + annotation.describe());
            }

            log.debug("参数个数: " + length);
            if (length > 0) {
                argsType = new StringBuffer(4);
                for (Object object : args) {
                    argsType.append(object.getClass().getTypeName() + ",");
                }
                log.debug("参数类型:" + argsType);

            }

            log.debug("请求参数: " + getParameter(method, args));
            log.debug("总耗时: " + delay + " ms");

        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 根据方法和传入的参数获取请求参数
     */
    private Object getParameter(Method method, Object[] args) {

        List<Object> argList = new ArrayList<>(10);
        Parameter[] parameters = method.getParameters();

        for (int i = 0; i < parameters.length; i++) {
            /**将RequestBody注解修饰的参数作为请求参数*/
            RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
            if (requestBody != null) {
                argList.add(args[i]);
            }
            /**将RequestParam注解修饰的参数作为请求参数*/
            RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
            if (requestParam != null) {
                Map<String, Object> map = new HashMap<>(16);
                String key = parameters[i].getName();
                if (!StringUtils.isEmpty(requestParam.value())) {
                    key = requestParam.value();
                }
                map.put(key, args[i]);
                argList.add(map);
            }
        }

        if (argList.size() == 0) {
            return null;
        }

        if (argList.size() == 1) {
            return argList.get(0);
        }

        return argList;

    }

}

3.打开aop代理

  aop:
    proxy-target-class: true

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值