AOP使用示例:日志采集功能

AOP使用示例:日志采集功能

背景: 目的是为了优化CalledListRequest接口,深入了解后发现这个接口写的不是那么好,循环调用某个接口。导致某些简单的查询被反复执行。从而效率。然后这个接口涉及到的业务逻辑太过于复杂,没敢直接改。而是新写了个接口取代它。但是为了做更充分的测试。先线上采集请求参数。然后进行测试。最后在发布上线是最好的方式。

功能以及原理介绍

为了收集线上这个接口(CalledListRequest)的请求参数。

原理:写一个方法,将传递过来的参数全部插入到数据库的日志表里面。
但是为了减少侵入性(就是不改变原有接口的实现代码)。我这里使用了AOP切入的方式。同时配合apollo做了一个开关(控制什么时候开始收集,什么时候关闭收集)

主要的一个技能点就是对AOP的应用了,之前其实没有实际工作去应用到AOP,这一次算是个机会了

其实特别简单,直接的核心代码就好了。没有复杂的东西

核心代码

package com.centanet.bizcom.config.log;

import com.alibaba.fastjson.JSON;
import com.centanet.bizcom.config.apollo.ApolloConfig;
import com.centanet.bizcom.config.ddb.MultiTenantChanger;
import com.centanet.bizcom.mapper.BizMapper;
import com.centanet.bizcom.model.entity.LogCollection;
import com.centanet.bizcom.util.CityHelper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 该类的功能是为了收集日志
 * 方便切换接口时使用
 * @Author: wbdengtt
 * @Date: 2020/10/13 14:58
 */
 //声明切面
@Aspect
// 交给Spring管理bean
@Component
public class LogCollectAspect {
	// 注入logCollection 这个就是一个简单实体entity。
    @Autowired
    private LogCollection logCollection;
    // 这是将实体存到数据库的mapper
    @Autowired
    private BizMapper bizMapper;
    // 拦截CalledController.calledListRequest方法。通过这个配置。可以拦截更多东西,这个规则相信的可以看下面的参考文章
    @Pointcut("execution(* com.centanet.bizcom.controller.CalledController.calledListRequest(..))")
    public void myPointCut() {
        // 这个其实就是一个切点,不需要方法内容
    }
    // 这个是具体实现拦截参数,并将参数日志写入到数据库的方法
    @Before("myPointCut()")
    public void logCollect(JoinPoint joinPoint) {
    	// 这个是在apoll配置的开关(就是一个String变量)。如果开了才进行下面的拦截。
        boolean isLogCollect = "true".equalsIgnoreCase(ApolloConfig.getWebValue(CityHelper.getCityCode(),"isLogCollectionOpen"))
                && ApolloConfig.getWebValue(CityHelper.getCityCode(),"logCollectCity").contains(CityHelper.getCityen());
        if (isLogCollect) {
        	// 设置logCollection的日期字段
            logCollection.setRowDate(new Date());
            // 获取当前HttpServletRequest 对象 这个是为了拿到各种我需要的信息。关于HttpServletRequest 下面有提供参考链接看相信的介绍
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
			//设置logCollection的实体字段,这里是请求类型.城市
			logCollection.setMethodName(request.getMethod()+"."+CityHelper.getCityen());
            //request.getQueryString() 只能拿到get请求的参数。如果是post请求,得通过joinPoint才能拿到参数(这个不需要手动声明,应该是SpringAOP哪里给自动注入了) 
            logCollection.setMessage(JSON.toJSONString(joinPoint.getArgs()));
            if (logCollection.getMessage() ==null){
                logCollection.setMessage("没能拿到参数");
            }
            // request.getRequestURI()获取方法名
            logCollection.setFullName(request.getRequestURI());
            // 写入数据库  MultiTenantChanger是因为我有多个数据库,但是这里的操作其实就是讲实体装入数据库
            MultiTenantChanger.setDataSourceType(CityHelper.getCityCode()+MultiTenantChanger.CENTA_BIZ);
            bizMapper.insertLogCollection(logCollection);
            MultiTenantChanger.removeRouteKey();
        }
    }
}

我给代码加了许多注释。应该是比较好明白的

参考文章:
Joinpoint:
https://blog.csdn.net/qq_15037231/article/details/80624064
HttpServletRequest相关:
https://blog.csdn.net/cold___play/article/details/100920952
execution规则:
https://blog.csdn.net/weixin_39209728/article/details/83752754
AOP简介(这篇是我自己以前写的)
https://blog.csdn.net/m0_37628958/article/details/106201011

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值