| | |
| | | package com.panzhihua.service_community.config; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.IntStream; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | 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.core.LocalVariableTableParameterNameDiscoverer; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.panzhihua.common.model.vos.R; |
| | | import com.panzhihua.common.utlis.DateUtils; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | /** |
| | | * 应用模块名称 |
| | | * <p> |
| | | * 代码描述 |
| | | * <p> |
| | | * 拦截controller,输出入参、响应内容和响应时间 Copyright: Copyright (C) 2021 XXX, Inc. All rights reserved. |
| | | * <p> |
| | | * Company: 成都呐喊信息技术有限公司 |
| | | * <p> |
| | | * |
| | | * @author manailin |
| | | * @since 2021/8/24 15:30 |
| | | */ |
| | | @Slf4j |
| | | @Aspect |
| | | @Component |
| | | public class ParamOutAspect { |
| | | |
| | | /** |
| | | * 记录特定日志的声明 |
| | | */ |
| | | private final Logger slowClassAndMethodLog = LoggerFactory.getLogger("slowClassAndMethodLog"); |
| | | /** |
| | | * 设定方法的执行时间限制毫秒数 |
| | | */ |
| | | private long maxReduceTime = 100; |
| | | |
| | | @Pointcut("execution(* com.panzhihua.service_community.api..*.*(..)) || execution (public * com.panzhihua.service_community.service..* (..))") |
| | | public void aspect() {} |
| | | |
| | | /** |
| | | * [方法描述] 环绕通知,拦截controller,输出请求参数、响应内容和响应时间 |
| | | * |
| | | * @param joinPoint |
| | | * @return java.lang.Object |
| | | * @author manailin |
| | | * @date 2021/8/24 17:04 |
| | | */ |
| | | @Around("aspect()") |
| | | public Object processLog(ProceedingJoinPoint joinPoint) { |
| | | log.info("进入方法性能检查方法"); |
| | | Method method = ((MethodSignature)joinPoint.getSignature()).getMethod(); |
| | | String className = method.getDeclaringClass().getName(); |
| | | // 获取方法名称 |
| | | String methodName = method.getName(); |
| | | // 获取参数名称 |
| | | LocalVariableTableParameterNameDiscoverer paramNames = new LocalVariableTableParameterNameDiscoverer(); |
| | | String[] params = paramNames.getParameterNames(method); |
| | | // 获取参数 |
| | | Object[] args = joinPoint.getArgs(); |
| | | // 过滤掉request和response,不能序列化 |
| | | List<Object> filteredArgs = Arrays.stream(args) |
| | | .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse))) |
| | | .collect(Collectors.toList()); |
| | | JSONObject rqsJson = new JSONObject(); |
| | | rqsJson.put("rqsMethod", methodName); |
| | | rqsJson.put("rqsTime", DateUtils.getCurrentDateStr_MS()); |
| | | if (ObjectUtils.isEmpty(filteredArgs)) { |
| | | rqsJson.put("rqsParams", null); |
| | | } else { |
| | | // 拼接请求参数 |
| | | Map<String, Object> rqsParams = IntStream.range(0, filteredArgs.size()).boxed() |
| | | .collect(Collectors.toMap(j -> params[j], j -> filteredArgs.get(j))); |
| | | rqsJson.put("rqsParams", rqsParams); |
| | | } |
| | | log.info(className + ":" + methodName + "请求信息为:" + rqsJson.toJSONString()); |
| | | Object resObj = null; |
| | | long startTime = System.currentTimeMillis(); |
| | | try { |
| | | // 执行原方法 |
| | | resObj = joinPoint.proceed(args); |
| | | } catch (Throwable e) { |
| | | log.error(className + ":" + methodName + "方法执行异常!", e); |
| | | // throw new ServiceException(methodName + "方法执行异常!"); |
| | | } |
| | | long endTime = System.currentTimeMillis(); |
| | | if (resObj != null) { |
| | | if (resObj instanceof R) { |
| | | // 输出响应信息 |
| | | R resJson = (R)resObj; |
| | | // 打印耗时的信息 |
| | | this.printExecTime(className , methodName,rqsJson,resJson, startTime, endTime); |
| | | return resJson; |
| | | } else { |
| | | return resObj; |
| | | } |
| | | } else { |
| | | return R.ok(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * [方法描述] 打印方法执行耗时的信息,如果超过了一定的时间,才打印 |
| | | * |
| | | * @param methodName |
| | | * 执行方法名 |
| | | * @param startTime |
| | | * 执行开始时间 |
| | | * @param endTime |
| | | * 执行结束时间 |
| | | * @author manailin |
| | | * @date 2021/8/24 17:05 |
| | | */ |
| | | private void printExecTime(String className,String methodName, JSONObject rqsJson,R resJson, long startTime, long endTime) { |
| | | long diffTime = endTime - startTime; |
| | | if (diffTime > maxReduceTime) { |
| | | slowClassAndMethodLog.info(className+":"+methodName + " 方法执行耗时:" + diffTime + " ms"); |
| | | slowClassAndMethodLog.info(methodName + " 请求参数:" +rqsJson.toJSONString()); |
| | | slowClassAndMethodLog.info(className + " 响应信息:" + JSONObject.toJSONString(resJson)); |
| | | } |
| | | // TODO 可以集成redis,将每个controller的执行时间追加到redis中,再用定时每周一次同步到库中 |
| | | } |
| | | |
| | | } |
| | | //package com.panzhihua.service_community.config; |
| | | // |
| | | //import java.lang.reflect.Method; |
| | | //import java.util.Arrays; |
| | | //import java.util.List; |
| | | //import java.util.Map; |
| | | //import java.util.stream.Collectors; |
| | | //import java.util.stream.IntStream; |
| | | // |
| | | //import javax.servlet.http.HttpServletRequest; |
| | | //import javax.servlet.http.HttpServletResponse; |
| | | // |
| | | //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.core.LocalVariableTableParameterNameDiscoverer; |
| | | //import org.springframework.stereotype.Component; |
| | | //import org.springframework.util.ObjectUtils; |
| | | // |
| | | //import com.alibaba.fastjson.JSONObject; |
| | | //import com.panzhihua.common.model.vos.R; |
| | | //import com.panzhihua.common.utlis.DateUtils; |
| | | // |
| | | //import lombok.extern.slf4j.Slf4j; |
| | | // |
| | | ///** |
| | | // * 应用模块名称 |
| | | // * <p> |
| | | // * 代码描述 |
| | | // * <p> |
| | | // * 拦截controller,输出入参、响应内容和响应时间 Copyright: Copyright (C) 2021 XXX, Inc. All rights reserved. |
| | | // * <p> |
| | | // * Company: 成都呐喊信息技术有限公司 |
| | | // * <p> |
| | | // * |
| | | // * @author manailin |
| | | // * @since 2021/8/24 15:30 |
| | | // */ |
| | | //@Slf4j |
| | | //@Aspect |
| | | //@Component |
| | | //public class ParamOutAspect { |
| | | // |
| | | // /** |
| | | // * 记录特定日志的声明 |
| | | // */ |
| | | // private final Logger slowClassAndMethodLog = LoggerFactory.getLogger("slowClassAndMethodLog"); |
| | | // /** |
| | | // * 设定方法的执行时间限制毫秒数 |
| | | // */ |
| | | // private long maxReduceTime = 100; |
| | | // |
| | | // @Pointcut("execution(* com.panzhihua.service_community.api..*.*(..)) || execution (public * com.panzhihua.service_community.service..* (..))") |
| | | // public void aspect() {} |
| | | // |
| | | // /** |
| | | // * [方法描述] 环绕通知,拦截controller,输出请求参数、响应内容和响应时间 |
| | | // * |
| | | // * @param joinPoint |
| | | // * @return java.lang.Object |
| | | // * @author manailin |
| | | // * @date 2021/8/24 17:04 |
| | | // */ |
| | | // @Around("aspect()") |
| | | // public Object processLog(ProceedingJoinPoint joinPoint) { |
| | | // log.info("进入方法性能检查方法"); |
| | | // Method method = ((MethodSignature)joinPoint.getSignature()).getMethod(); |
| | | // String className = method.getDeclaringClass().getName(); |
| | | // // 获取方法名称 |
| | | // String methodName = method.getName(); |
| | | // // 获取参数名称 |
| | | // LocalVariableTableParameterNameDiscoverer paramNames = new LocalVariableTableParameterNameDiscoverer(); |
| | | // String[] params = paramNames.getParameterNames(method); |
| | | // // 获取参数 |
| | | // Object[] args = joinPoint.getArgs(); |
| | | // // 过滤掉request和response,不能序列化 |
| | | // List<Object> filteredArgs = Arrays.stream(args) |
| | | // .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse))) |
| | | // .collect(Collectors.toList()); |
| | | // JSONObject rqsJson = new JSONObject(); |
| | | // rqsJson.put("rqsMethod", methodName); |
| | | // rqsJson.put("rqsTime", DateUtils.getCurrentDateStr_MS()); |
| | | // if (ObjectUtils.isEmpty(filteredArgs)) { |
| | | // rqsJson.put("rqsParams", null); |
| | | // } else { |
| | | // // 拼接请求参数 |
| | | // Map<String, Object> rqsParams = IntStream.range(0, filteredArgs.size()).boxed() |
| | | // .collect(Collectors.toMap(j -> params[j], j -> filteredArgs.get(j))); |
| | | // rqsJson.put("rqsParams", rqsParams); |
| | | // } |
| | | // log.info(className + ":" + methodName + "请求信息为:" + rqsJson.toJSONString()); |
| | | // Object resObj = null; |
| | | // long startTime = System.currentTimeMillis(); |
| | | // try { |
| | | // // 执行原方法 |
| | | // resObj = joinPoint.proceed(args); |
| | | // } catch (Throwable e) { |
| | | // log.error(className + ":" + methodName + "方法执行异常!", e); |
| | | // // throw new ServiceException(methodName + "方法执行异常!"); |
| | | // } |
| | | // long endTime = System.currentTimeMillis(); |
| | | // if (resObj != null) { |
| | | // if (resObj instanceof R) { |
| | | // // 输出响应信息 |
| | | // R resJson = (R)resObj; |
| | | // // 打印耗时的信息 |
| | | // this.printExecTime(className , methodName,rqsJson,resJson, startTime, endTime); |
| | | // return resJson; |
| | | // } else { |
| | | // return resObj; |
| | | // } |
| | | // } else { |
| | | // return R.ok(); |
| | | // } |
| | | // } |
| | | // |
| | | // /** |
| | | // * [方法描述] 打印方法执行耗时的信息,如果超过了一定的时间,才打印 |
| | | // * |
| | | // * @param methodName |
| | | // * 执行方法名 |
| | | // * @param startTime |
| | | // * 执行开始时间 |
| | | // * @param endTime |
| | | // * 执行结束时间 |
| | | // * @author manailin |
| | | // * @date 2021/8/24 17:05 |
| | | // */ |
| | | // private void printExecTime(String className,String methodName, JSONObject rqsJson,R resJson, long startTime, long endTime) { |
| | | // long diffTime = endTime - startTime; |
| | | // if (diffTime > maxReduceTime) { |
| | | // slowClassAndMethodLog.info(className+":"+methodName + " 方法执行耗时:" + diffTime + " ms"); |
| | | // slowClassAndMethodLog.info(methodName + " 请求参数:" +rqsJson.toJSONString()); |
| | | // slowClassAndMethodLog.info(className + " 响应信息:" + JSONObject.toJSONString(resJson)); |
| | | // } |
| | | // // TODO 可以集成redis,将每个controller的执行时间追加到redis中,再用定时每周一次同步到库中 |
| | | // } |
| | | // |
| | | //} |