package com.panzhihua.service_user.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.Pointcut;
|
import org.aspectj.lang.reflect.MethodSignature;
|
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
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 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<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();
|
} 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中,再用定时每周一次同步到库中
|
}
|
|
}
|