springboot AOP 拦截获取记录日志信息

1.添加依赖

通过spring boot创建好工程后,添加如下依赖,不然工程中无法使用切面的注解,就无法对制定的方法进行拦截

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency

2. 自定义注解类 LogRequest

/**
 * @ClassNameLogRequest.java
 * @author shengwu
 * @date 2019-10-19
 * @Target 此注解的作用目标,括号里METHOD的意思说明此注解只能加在方法上面
 * @Retention 注解的保留位置,括号里RUNTIME的意思说明注解可以存在于运行时,可以用于反射
 * @Documented 说明该注解将包含在javadoc中
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogRequest {
    /**
     * 是否记录日志表中
     * @return
     */
    String logFlag() default "N";

    /**
     * 接口名称
     * @return
     */
    String interfaceName() default "";
}

3. 切面类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;

/**
 * 此类为一个切面类,主要作用就是对接口的请求进行拦截
 * 拦截的方式,只需要在指定接口方法上面加上@LogRequest注解即可
 *
 * @author shengwu
 * @version 1.0
 * @since 2019/09/28
 */
@Aspect
@Component
public class RequestAspect {
    private static final Logger logger = LoggerFactory.getLogger(RequestAspect.class);
    @Autowired
    private IInterfaceLogService iInterfaceLogService;
    /**
     * 表示在执行被@LogRequest注解修饰的方法之前 会执行doBefore()方法
     *
     * @param joinPoint 连接点,就是被拦截点
     */
    @Around(value = "@annotation(LogRequest)")
    public Object doAround(ProceedingJoinPoint joinPoint, LogRequest LogRequest) throws Throwable {
        Long start = System.currentTimeMillis();
        try {
            Object result = joinPoint.proceed();
            this.methodAround(joinPoint,result,start,LogRequest.logFlag(),LogRequest.interfaceName(),true);
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            this.methodAround(joinPoint,throwable.getMessage(),start,LogRequest.logFlag(),LogRequest.interfaceName(),false);
            throw throwable;
        }
    }

}

4. 日志方法

 /**
     *
     * @param joinPoint
     * @param object 返回对象值
     * @param startTime 方法开始时间
     * @param logFlag 是否插入日志
     * @param requestStatus 本次请求状态
     *
     */
    public void methodAround(JoinPoint joinPoint,Object object,Long startTime,String logFlag,String interfaceName,Boolean requestStatus) {
        //获取到请求的属性
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        //获取到请求对象
        HttpServletRequest request = attributes.getRequest();
        //URL:根据请求对象拿到访问的地址
        logger.info("url={}" , request.getRequestURL());
        logger.info("接口名称={}" , interfaceName);
        logger.info("代理对象自己:{}" + joinPoint.getThis());
        //获取传入目标方法的参数
        Object[] args = joinPoint.getArgs();
        Long time = (System.currentTimeMillis()-startTime);
        logger.info("执行时间长{}",time);
        Long endTime = System.currentTimeMillis();
        Date date = new Date(startTime);
        InterfaceLogDTO interfaceLogDTO = new InterfaceLogDTO();
        String uuid = UUID.randomUUID().toString();
        interfaceLogDTO.setInvokeKey(uuid);
        //微服务应用名
        interfaceLogDTO.setServerCode(serverCode);
        interfaceLogDTO.setRequestTime(date);
        interfaceLogDTO.setInterfaceResponseTime(endTime-startTime);
        interfaceLogDTO.setServerName(interfaceName);
        interfaceLogDTO.setApplicationCode(applicationInitListener.getServerIpPort());
        interfaceLogDTO.setUserAgent(request.getHeader("user-agent"));
        CustomUserDetails customClient = DetailsHelper.getUserDetails();
        if (customClient==null||customClient.getOrganizationId()==null) {
            logger.error("接口"+interfaceName+"租户获取空");
            return;
        }
        interfaceLogDTO.setTenantId(customClient.getOrganizationId());
        interfaceLogDTO.setClientId(customClient.getClientId()==null?null:String.valueOf(customClient.getClientId()));
        interfaceLogDTO.setInterfaceUrl(request.getRequestURL().toString());
        interfaceLogDTO.setRequestMethod(request.getMethod());
        interfaceLogDTO.setIp(request.getRemoteAddr());
        interfaceLogDTO.setInterfaceRequestTime(date);
        //明细
        InterfaceLogDtlDTO interfaceLogDtlDTO = new InterfaceLogDtlDTO();
        interfaceLogDTO.setInterfaceLogDtlDTO(interfaceLogDtlDTO);
        interfaceLogDtlDTO.setInvokeKey(uuid);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < args.length; i++) {
            try {
                stringBuilder.append(objectMapper.writeValueAsString(args[i]));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        interfaceLogDtlDTO.setInterfaceReqBodyParam(stringBuilder.toString());
        String interfaceRespContent =null;
        try {
            if (result!=null) {
                //返回内容
                interfaceRespContent = objectMapper.writeValueAsString(result);
            }

        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        if (requestStatus){
            interfaceLogDtlDTO.setInterfaceRespContent(interfaceRespContent);
            interfaceLogDTO.setResponseStatus(SUCCESS);
            interfaceLogDTO.setInterfaceResponseStatus(SUCCESS);
        }
        if (!requestStatus){
            interfaceLogDtlDTO.setStacktrace(interfaceRespContent);
            interfaceLogDTO.setResponseStatus(FAIL);
            interfaceLogDTO.setInterfaceResponseStatus(FAIL);
        }
        if(!FLAG_Y.equals(logFlag)){
            logger.info("出站信息{}",interfaceLogDTO.toString());
            return;
        }
    }

猜你喜欢

转载自www.cnblogs.com/wushenghfut/p/11569604.html