package com.panzhihua.service_bracelet.config; import com.alibaba.fastjson.JSONObject; import com.panzhihua.common.model.vos.R; import com.panzhihua.common.utlis.DateUtils; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.util.ObjectUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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; /** * 应用模块名称 *

* 代码描述 *

* 拦截controller,输出入参、响应内容和响应时间 Copyright: Copyright (C) 2021 XXX, Inc. All rights reserved. *

* Company: 成都呐喊信息技术有限公司 *

* * @author manailin * @since 2021/8/24 15:30 */ @Slf4j // @Aspect // @Component public class ParamOutAspect { /** * 设定方法的执行时间限制毫秒数 */ private long maxReduceTime = 2000; @Pointcut("execution (public * com.panzhihua.service_user.api..* (..))||execution (public * com.panzhihua.service_user.service..* (..))") public void aspect() {} /** * [方法描述] 环绕通知,拦截controller,输出请求参数、响应内容和响应时间 * * @param joinPoint aspect() * @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 = joinPoint.getSignature().getDeclaringTypeName(); // 获取方法名称 String methodName = method.getName(); // 获取参数名称 LocalVariableTableParameterNameDiscoverer paramNames = new LocalVariableTableParameterNameDiscoverer(); String[] params = paramNames.getParameterNames(method); // 获取参数 Object[] args = joinPoint.getArgs(); // 过滤掉request和response,不能序列化 List 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 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(); } catch (Throwable e) { log.error(className + ":" + methodName + "方法执行异常!", e); } long endTime = System.currentTimeMillis(); // 打印耗时的信息 this.printExecTime(className + ":" + methodName, startTime, endTime); if (resObj != null) { // 打印返回消息 log.info(className + ":" + methodName + "响应信息为:" + JSONObject.toJSON(resObj)); return resObj; } else { return R.ok(); } } /** * [方法描述] 打印方法执行耗时的信息,如果超过了一定的时间,才打印 * * @param classAndMethodName * 执行方法名 * @param startTime * 执行开始时间 * @param endTime * 执行结束时间 * @author manailin * @date 2021/8/24 17:05 */ private void printExecTime(String classAndMethodName, long startTime, long endTime) { long diffTime = endTime - startTime; if (diffTime > maxReduceTime) { log.info(classAndMethodName + " 方法执行耗时:" + diffTime + " ms"); } // TODO 可以集成redis,将每个controller的执行时间追加到redis中,再用定时每周一次同步到库中 } }