SpringBoot使用AOP的方式监控API调用情况

309 阅读1分钟

1.导入pom依赖

        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.5</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>

2.创建log实体类

@Builder
@Data
public class FlowApiLog implements Serializable {

    private String id;

    private String url;

    private String createTime;

    private String source;      //来源,预留给分布式使用

    private String ipaddr;

}

3.创建切面

@Slf4j
@Aspect
@Component
public class FlowApiAspect {
    /*时间格式*/
    private static String YMDMHS = "yyyy-MM-dd HH:mm:ss";

    @Autowired
    private ApiLogService apiLogService;

    //分布式预留
   /* @Value(value = "${spring.application.name}")
    private String serverName;*/

    @Pointcut(value =  "@annotation(org.springframework.web.bind.annotation.GetMapping) ||" +
            "@annotation(org.springframework.web.bind.annotation.PostMapping) ||" +
            "@annotation(org.springframework.web.bind.annotation.PutMapping) ||" +
            "@annotation(org.springframework.web.bind.annotation.DeleteMapping) ||" +
            "@annotation(org.springframework.web.bind.annotation.RequestMapping) ")
    public void  flowApi(){
    }

    //环绕式实现
    @Around(value = "flowApi()")
    public Object flowControl(ProceedingJoinPoint joinPoint){
        Object proceed = null;
        long time = System.currentTimeMillis();
        try {
            proceed = joinPoint.proceed();
            time = System.currentTimeMillis() - time;
            log.info("方法执行消耗时间 = " + time);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {
            //方法执行后
            saveFlowApi(joinPoint);
        }
        return proceed;
    }

    private void saveFlowApi(ProceedingJoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        
        String re = "(本地前缀|部署上线的前缀)";  //正则判断环境
        //获取 URL
        String url = request.getRequestURL().toString().replaceAll(re,"");
        //获取调用者的IP
//        String ip = IPUtils.getRemoteHost(request);
        //调用的时间
        String date = DateFormatUtils.format(new Date(), YMDMHS);

        FlowApiLog flowApiLog = FlowApiLog.builder()
                .id(UUID.randomUUID().toString().replace("-",""))
                .url(url)
                .createTime(date)
//                .source(serverName)       //分布式预留字段
                .ipaddr(request.getRemoteAddr()).build();
        //这里可以进行持久化
        apiLogService.insertApiLog(flowApiLog);
        log.info("接口调用信息{}",flowApiLog);
    }
}