自定义注解打印日志

 公司功能重做,有一些老的接口需要弃用,但是旧版本的APP调用就会报错,所以需要对这些接口处理,返回版本过低提示,于是乎写了一个注解,调用这个接口的都会返回版本过低。

写完之后闲来无事,想到最近系统压力过大,有些接口需要增加耗时计算,想写一个注解,自定义打印日志,说干就干。

定义注解名称

参考网上查的资源,进行注解的自定义,level用来判断都需要打印哪些日志

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface WebLog {
    String value() default "";

    Level[] level() default {};

    enum Level{
        URL,// 请求路径
        METHOD,//请求方法
        ARGS,//请求参数
        RESPONSE,//返回数据
    }
}

实现注解切面

有了注解名称,对注解切面进行实现,可以通过输入参数判断用户都需要打印哪些参数,特此记录,干完收工。

@Aspect
@Component
//@Profile({"dev","test"})
public class WebLogAspect {

    private static final Logger log = Logger.getLogger(WebLogAspect.class);

    @Pointcut("@annotation(com.cpit.icp.appserver.annotation.WebLog)")
    public void webLog(){}

    private String PREFIX = "";
    private List<WebLog.Level> LEVEL = new ArrayList<>();

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Exception {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        WebLog aspectValue = getAspectValue(joinPoint);
        PREFIX = aspectValue.value();
        LEVEL = Arrays.asList(aspectValue.level());
        if(LEVEL.contains(WebLog.Level.URL)){
            log.info(PREFIX + " URL:  "+request.getRequestURL().toString());
        }
        if(LEVEL.contains(WebLog.Level.METHOD)){
            log.info(PREFIX + " METHOD:  " + request.getMethod());
        }
        if(LEVEL.contains(WebLog.Level.ARGS)){
            log.info("ARGS:  " + new Gson().toJson(joinPoint.getArgs()));
        }

    }

    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        // 打印出参
        if(LEVEL.contains(WebLog.Level.RESPONSE)){
            log.info(PREFIX + " RESPONSE  :"+ new Gson().toJson(result));
        }
        // 执行耗时
        log.info(PREFIX + " [耗时计算]:  " + (System.currentTimeMillis() - startTime) + " ms");
        return result;
    }

    public WebLog getAspectValue(JoinPoint joinPoint)
            throws Exception {
        Class<?> targetCls=joinPoint.getTarget().getClass();
        Signature signature=joinPoint.getSignature();
        MethodSignature ms= (MethodSignature)signature;
        Method targetMethod=targetCls.getDeclaredMethod(ms.getName(),ms.getParameterTypes());
        return targetMethod.getAnnotation(WebLog.class);
    }


}

附使用方法:

   @WebLog(value = "获取所有充电站",level = {WebLog.Level.URL, WebLog.Level.METHOD, WebLog.Level.RESPONSE})

另一种实现

来更新一波,通过实验,还有一种方法,不进行切点的定义,直接在Before上使用注解,这样免去上面用各种反射取得注解中参数的麻烦

@Aspect
@Component
//@Profile({"dev","test"})
public class WebLogAspect {

    private static final Logger log = Logger.getLogger(WebLogAspect.class);


    @Before("@annotation(webLog)")
    public void doBefore(JoinPoint joinPoint,WebLog webLog) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String PREFIX = webLog.value();
        List<WebLog.Level> LEVEL = Arrays.asList(webLog.level());
        if(LEVEL.contains(WebLog.Level.URL)){
            log.info(PREFIX + " URL:  "+request.getRequestURL().toString());
        }
        if(LEVEL.contains(WebLog.Level.METHOD)){
            log.info(PREFIX + " METHOD:  " + request.getMethod());
        }
        if(LEVEL.contains(WebLog.Level.ARGS)){
            log.info("ARGS:  " + new Gson().toJson(joinPoint.getArgs()));
        }

    }

    @Around("@annotation(webLog)")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint,WebLog webLog) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        String PREFIX = webLog.value();
        List<WebLog.Level> LEVEL = Arrays.asList(webLog.level());
        // 打印出参
        if(LEVEL.contains(WebLog.Level.RESPONSE)){
            log.info(PREFIX + " RESPONSE  :"+ new Gson().toJson(result));
        }
        // 执行耗时
        log.info(PREFIX + " [耗时计算]:  " + (System.currentTimeMillis() - startTime) + " ms");
        return result;
    }

}

区别在于将注解对象放在入参中,直接取用即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值