All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yanyun.log.aop.DealAopSendMsg Maven / Gradle / Ivy

There is a newer version: 1.0.8
Show newest version
package com.yanyun.log.aop;

import com.yanyun.auth.dto.ResultDto;
import com.yanyun.log.model.LogModel;
import com.yanyun.log.service.MQSendEventService;
import com.yanyun.log.utils.LogUtils;
import com.yanyun.log.websocket.LogSocketConfig;
import io.kubemq.sdk.basic.ServerAddressNotSuppliedException;
import io.swagger.annotations.ApiOperation;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;

/**
 * 做AOP拦截,拦截带有Swagger注解的方法,统计用户行为
 * 数据的组装在此处做处理
 */
@Aspect
public class DealAopSendMsg {
    //日志
    private static final Logger logger = LoggerFactory.getLogger(DealAopSendMsg.class);
    //mq发送消息的组件
    private MQSendEventService mqSendEventService;

    //连接池组件
    private ExecutorService senderThreadPool;
    //远程调用组件
    private RestTemplate restTemplate;

    private  String ip2RegionAddr;

    public DealAopSendMsg(MQSendEventService mqSendEventService, ExecutorService senderThreadPool, RestTemplate restTemplate,String ip2RegionAddr) {

        this.mqSendEventService = mqSendEventService;
        this.senderThreadPool = senderThreadPool;
        this.restTemplate = restTemplate;
        this.ip2RegionAddr = ip2RegionAddr;
    }

    //拦截带有apiOperation注解的方法进行统计
    @Pointcut("@annotation(io.swagger.annotations.ApiOperation)")
    public void pointCut() {
    }

    /**
     * 做环绕通知,处理拦截的用户行为
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("pointCut()")
    public Object deal(ProceedingJoinPoint joinPoint) throws Throwable {
        //执行结果
        Object proceed = null;
        //日志对象
        LogModel logModel = new LogModel();
        try {
            proceed = joinPoint.proceed();
            if (proceed instanceof ResultDto) {
                Integer code = ((ResultDto) proceed).getCode();
                if (code != null && code == 200) {
                    logModel.setOptionResult("成功");
                } else {
                    logModel.setOptionResult("失败");
                }
            } else {
                //如果不是固定的返回值,那么直接返回成功
                logModel.setOptionResult("成功.");
            }
        } catch (Exception e) {
            logModel.setOptionResult("异常");
        }
        //获取用户的登录信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (null == authentication || authentication instanceof AnonymousAuthenticationToken) {
            //如果是匿名登录
            logModel.setUsername("匿名用户");
        } else {
            //是登录的用户
            logModel.setUsername((String) authentication.getPrincipal());
        }
        //获取请求对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //从请求中获取Ip
        String ip = LogUtils.getIp(request);
        logModel.setIp(ip);
        //从请求中获取浏览器类型
        String browser = LogUtils.getBrowser(request);
        logModel.setBrowser(browser);
        //用户操作时间
        long optionTime = System.currentTimeMillis();
        logModel.setOptionTime(optionTime);
        //采集用户操作
        if (joinPoint.getSignature() instanceof MethodSignature) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            //获取操作路径
            String path = joinPoint.getTarget().getClass().getName() + "." + signature.getName();
            logModel.setClassPath(path);
            ApiOperation annotation = signature.getMethod().getAnnotation(ApiOperation.class);
            //如果标记了swagger注解说明了方法,那么进行采集数据
            if (annotation != null && !StringUtils.isEmpty(annotation.value())) {
                //获取操作类型
                logModel.setOptionType(annotation.value());
            }
            if (annotation != null && !StringUtils.isEmpty(annotation.notes())) {
                //获取详细操作
                logModel.setOption(annotation.notes());
            }
        }

        //异步线程执行 采集用户行为数据到MQ
        senderThreadPool.submit(() -> {
            //发送数据到MQ
            try {
                //获取ip对应的区域
                String area = getArea(ip);
                logModel.setArea(area);
                //将日志消息发布到Channel中
                mqSendEventService.sendLogInfoToMqEvent(logModel);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ServerAddressNotSuppliedException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        });
        return proceed;//返回执行结果
    }

    /**
     * 获取Ip对应的地址区域
     * @param ip
     * @return
     */
    private String getArea(String ip) {
        if (!StringUtils.isEmpty(ip) && ip.equalsIgnoreCase("0:0:0:0:0:0:0:1")){
            return "局域网";
        }
        //远程调用,并发送数据
        try {
            String ipAddre = restTemplate.getForObject(ip2RegionAddr+"?ip="+ip, String.class);
            if (!StringUtils.isEmpty(ipAddre)) {
                String[] split = ipAddre.split(",");
                if (split.length > 1) {
                    //如果得到了正确的解析,那么地址为
                    String ipAddr = split[1];
                    //空行截取
                    String[] s = ipAddr.split(" ");
                    return s[0];
                } else {
                    return null;
                }
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("获取Ip对应的区域地址失败,请检查网络服务");
            return null;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy