【自定義註解】實現接口請求參數和返回參數的打印

本篇博客主要是實現自定義註解,通過在方法中使用該註解,打印出該方法的請求參數以及返回參數,用於排查問題。減少日誌的打印。

方法枚舉:

package cn.eric.jdktools.annotation;

/**
 * 方法返回參數枚舉
 * @Author wilsonm
 * @Date 2020/4/13 1:02 下午
 * @Param
 * @return
 **/
public enum LogType {

    TIME("TIME", "方法調用時間"),
    PARAM("PARAM", "參數打印");

    private String type;
    private String desc;

    LogType(String type, String desc) {
        this.type = type;
        this.desc = desc;
    }
}

自定義註解:

package cn.eric.jdktools.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogUseTime {
    /**
     * 描述
     *
     * @return
     */
    String desc() default "";

    /**
     * 需要打印的日誌形式
     *
     * @return
     */
    LogType type() default LogType.PARAM;
}

方法實現:

package cn.eric.jdktools.annotation;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 接口調用耗時 入參返回參數打印切面
 * @author: wilsonm
 * @date: 2020/4/13 1:02 下午
 **/
@Aspect
@Component
@Log4j2
public class LogUseTimeAspect {

    /**
     * 參數截止長度
     */
    private static int maxParamLen = 2000;

    @Pointcut("@annotation(cn.eric.jdktools.annotation.LogUseTime)")
    public void annotationCallTime() {
        // not need body
    }

    @Around(value = "annotationCallTime()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
        LogUseTime useTime = method.getAnnotation(LogUseTime.class);
        long startTime = System.currentTimeMillis();
        Object object = null;
        try {
            object = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            String argStr = getArgStr(proceedingJoinPoint.getArgs());
            long costTime = System.currentTimeMillis() - startTime;
            log.info("method:{}, in params:{}, out params:{}, use time:{}ms", method.getName(), argStr,
                    throwable.getMessage(), costTime);
            throw throwable;
        }
        long costTime = System.currentTimeMillis() - startTime;
        switch (useTime.type()) {
            case TIME:
                log.info("desc:{}, method:{},  use time:{}ms", useTime.desc(),
                        method.getName(), costTime);
                break;
            case PARAM:
                String argStr = getArgStr(proceedingJoinPoint.getArgs());
                String result = JSON.toJSONString(object);
                if (!StringUtils.isEmpty(result) && result.length() > maxParamLen) {
                    result = result.substring(0, maxParamLen) + "...";
                }
                if (StringUtils.isNotEmpty(useTime.desc())) {
                    log.info("desc:{}, method:{}, in params:{}, out params:{}, use time:{}ms", useTime.desc(),
                            method.getName(), argStr, result, costTime);
                } else {
                    log.info("method:{}, in params:{}, out params:{}, use time:{}ms", method.getName(), argStr,
                            result, costTime);
                }

                break;
            default:
        }

        return object;
    }

    private String getArgStr(Object[] args) {
        List<String> argList = Lists.newArrayList();
        try {
            for (Object obj : args) {
                String str = JSON.toJSONString(obj);
                if (StringUtils.isEmpty(str)) {
                    continue;
                }
                if (str.length() > maxParamLen) {
                    argList.add(str.substring(0, maxParamLen) + "...");
                } else {
                    argList.add(str);
                }
            }
        } catch (Exception e) {
            // ignore exception
        }
        return String.join("&", argList);
    }

}


相關依賴:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
                <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.2-jre</version>
        </dependency>
                <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

使用示例:

    @LogUseTime(desc = "獲取供應商完整信息")
    @GetMapping("info/fetch/mostInfo")
    public BaseDataVO getSupplierMostInfo(String supplierNo) {
        return successModel(supplierInfoServiceForRemote.findSupplierInfoAndAccount(supplierNo));
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章