栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

利用Aop记录Controller层日志信息

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

利用Aop记录Controller层日志信息

一 起因

今天接到了公司的一个需求,利用aop记录Controller层的日志信息。当时2个反应,一个是啊,终于不是做crud了,第二个是,呀,我没做过,可以吗?不行也只能行了,于是马上找博文看,毕竟当初学的时候只记得有切入点,还有一些方法了

二 选择方案

估计你们看到这里就有点郁闷了吧,还有方案选择?我也被惊讶到了,话不多说,放大佬截图

 

 

 

是不是看的一脸懵逼,最后我还是采用了aop记录日志信息,别问,问就是网友说的话,可持续发展(我会告诉你其它的我不会吗,哼(傲娇)) 

这个我主要讲一下应用中的问题吧,因为原理解释很多博文中都有分享

第一是开启注解,第二是声明切面类(好像在水诶)

我看到有些博文还写了自定义注解,但是我这里没用到,就不说了。

@Pointcut("@within(org.springframework.web.bind.annotation.RestController) || @annotation(org.springframework.web.bind.annotation.RestController)")
public void requestServer() {
}

这里我是这样写的,然后大家也可以用那种表达式写,都行

   @Around("requestServer()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Object result = proceedingJoinPoint.proceed();
        EpmsLogInfo logInfo = new EpmsLogInfo();
        logInfo.setLogModule("Controller");
        logInfo.setLogDescription("查看Controller层日志记录");
        logInfo.setLogResult("Y");
        logInfo.setLogTime(DateTime.now());
        String ip = IpUtil.getRealIp(request);
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String classMethod = String.format("%s.%s", proceedingJoinPoint.getSignature().getDeclaringTypeName(), proceedingJoinPoint.getSignature().getName());
        Map params = getRequestParamsByProceedingJoinPoint(proceedingJoinPoint);
        String info="用户ip地址为"+ip+" " +
                "url路径为"+url+" " +
                "请求方法为"+method+" " +
                "接口路径为"+classMethod+" " +
                "入参为"+JSON.toJSONString(params);
        logInfo.setLogInfo(info);
        int insert = epmsLogInfoMapper.insert(logInfo);
        logger.info("切面类测试"+JSON.toJSONString(logInfo));
        return result;



    }

因为我是把日志存到表中的,所以大家重点看info里的就行,然后这里我自作聪明的把返回类型改为void,结果就是因为result不返回,后端得不到结束信息,迟迟不肯执行下一步,然后导致前端得不到数据,就挺尴尬了

然后还写了一个抛错注解方法,

然后讲一下ip地址吧,一开始写的是getRemoteip,后面有听说这个得不到真实地址(可能通过代理服务器查询)就找了个工具类写了进去,当然还没测试,没办法测试,行不行就不知道了,反正能得到我的地址,记录这个主要是防止dos攻击

三 总结

我看到一些大佬发的文章说是为了向测试甩锅写了个这样的日志,但是小公司肯定不是了,毕竟人家要求你全能的,更多的是为了方便查看信息。然后其它大佬说的一些方案我也会找时间去尝试,毕竟mq和elasticsearch学过之后就没怎么用了,都忘的差不多了

四 源代码
package com.chinamobile.cmss.cpms.base.common.aop;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.chinamobile.cmss.cpms.base.common.utils.util.IpUtil;
import com.chinamobile.cmss.cpms.fjepms.common.util.DateUtils;
import com.chinamobile.cmss.cpms.fjepms.virtualWorkFlow.mapper.EpmsLogInfoMapper;
import com.chinamobile.cmss_projcet_entity.entity.virtualWorkFlow.EpmsLogInfo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;



@Component
@Aspect
@Slf4j
public class ControllerAspeect {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private EpmsLogInfoMapper epmsLogInfoMapper;

    
    @Pointcut("@within(org.springframework.web.bind.annotation.RestController) || @annotation(org.springframework.web.bind.annotation.RestController)")
    public void requestServer() {
    }

    @Around("requestServer()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Object result = proceedingJoinPoint.proceed();
        EpmsLogInfo logInfo = new EpmsLogInfo();
        logInfo.setLogModule("Controller");
        logInfo.setLogDescription("查看Controller层日志记录");
        logInfo.setLogResult("Y");
        logInfo.setLogTime(DateTime.now());
        String ip = IpUtil.getRealIp(request);
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String classMethod = String.format("%s.%s", proceedingJoinPoint.getSignature().getDeclaringTypeName(), proceedingJoinPoint.getSignature().getName());
        Map params = getRequestParamsByProceedingJoinPoint(proceedingJoinPoint);
        String info="用户ip地址为"+ip+" " +
                "url路径为"+url+" " +
                "请求方法为"+method+" " +
                "接口路径为"+classMethod+" " +
                "入参为"+JSON.toJSONString(params);
        logInfo.setLogInfo(info);
        int insert = epmsLogInfoMapper.insert(logInfo);
        logger.info("切面类测试"+JSON.toJSONString(logInfo));
        return result;



    }
    @AfterThrowing(pointcut = "requestServer()", throwing = "e")
    public void doAfterThrow(JoinPoint joinPoint, RuntimeException e) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        EpmsLogInfo logInfo = new EpmsLogInfo();
        logInfo.setLogModule("Controller");
        logInfo.setLogDescription("查看Controller层日志记录");
        logInfo.setLogResult("N");
        logInfo.setLogTime(DateTime.now());
        String ip =IpUtil.getRealIp(request);
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String classMethod = String.format("%s.%s", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
        Map params = getRequestParamsByJoinPoint(joinPoint);
        String info="用户ip地址为"+ip+" " +
                "url路径为"+url+" " +
                "请求方法为"+method+" " +
                "接口路径为"+classMethod+" " +
                "入参为"+JSON.toJSONString(params)+" " +
                "Exception:"+e;
        logInfo.setLogInfo(info);
        int insert = epmsLogInfoMapper.insert(logInfo);
        logger.info("切面类测试"+JSON.toJSONString(logInfo));

    }

    
    private Map getRequestParamsByProceedingJoinPoint(ProceedingJoinPoint proceedingJoinPoint) {
        //参数名
        String[] paramNames = ((MethodSignature)proceedingJoinPoint.getSignature()).getParameterNames();
        //参数值
        Object[] paramValues = proceedingJoinPoint.getArgs();

        return buildRequestParam(paramNames, paramValues);
    }

    private Map getRequestParamsByJoinPoint(JoinPoint joinPoint) {
        //参数名
        String[] paramNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames();
        //参数值
        Object[] paramValues = joinPoint.getArgs();

        return buildRequestParam(paramNames, paramValues);
    }

    private Map buildRequestParam(String[] paramNames, Object[] paramValues) {
        Map requestParams = new HashMap<>();
        for (int i = 0; i < paramNames.length; i++) {
            Object value = paramValues[i];

            //如果是文件对象
            if (value instanceof MultipartFile) {
                MultipartFile file = (MultipartFile) value;
                value = file.getOriginalFilename();  //获取文件名
            }

            requestParams.put(paramNames[i], value);
        }

        return requestParams;
    }

}
package com.chinamobile.cmss.cpms.base.common.utils.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



@Slf4j
public class IpUtil {
    private static final String IP_PATTERN = "^(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\b";

    private static final String UNKNOWN = "unknown";

    private static final String LOOPBACK_ADDRESS = "127.0.0.1";

    private static final String UNKNOWN_ADDRESS = "0:0:0:0:0:0:0:1";

    
    public static String getIpAddr(HttpServletRequest request) {
        String ip = "127.0.0.1";
        StringBuffer buffer = new StringBuffer();
        if (request != null) {
            ip = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }

            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }

            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        }
        return ip;

    }

    
    public static String getRealIp(HttpServletRequest request) {
        StringBuffer buffer = new StringBuffer();
        String ip = LOOPBACK_ADDRESS;
        if (request == null) {
            return ip;
        }

        ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (LOOPBACK_ADDRESS.equals(ip) || UNKNOWN_ADDRESS.equals(ip)) {
                //根据网卡取本机配置的IP
                try {
                    InetAddress inet = InetAddress.getLocalHost();
                    ip = inet.getHostAddress();
                } catch (UnknownHostException e) {
                    log.error("getRealIp occurs error, caused by: ", e);
                    buffer.append("getRealIp occurs error, caused by: "+e);
                }
            }
        }

        //"***.***.***.***".length() = 15
        int ipLength = 15;
        String separator = ",";
        if (ip != null && ip.length() > ipLength) {
            if (ip.indexOf(separator) > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        return buffer.append(" ip:"+ip).toString();
    }

    public static String getServiceIp() {
        Enumeration netInterfaces = null;
        String ipsStr = "";

        try {
            netInterfaces = NetworkInterface.getNetworkInterfaces();
            while (netInterfaces.hasMoreElements()) {
                NetworkInterface ni = netInterfaces.nextElement();
                Enumeration ips = ni.getInetAddresses();
                Pattern pattern = Pattern.compile(IP_PATTERN);
                while (ips.hasMoreElements()) {
                    String ip = ips.nextElement().getHostAddress();
                    Matcher matcher = pattern.matcher(ip);
                    if (matcher.matches() && !"127.0.0.1".equals(ip)) {
                        ipsStr = ip;
                    }
                }
            }
        } catch (Exception e) {
            log.error("getServiceIp occurs error, caused by: ", e);
        }

        return ipsStr;
    }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025059.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号