模块执行时间监控
想要了解各个接口具体执行时间,需要计算方法执行开始到方法执行结束所用的时间,下面通过AOP+注解的方式来实现此功能。想要获取方法执行的时间只需加上注解即可。
首先新建注解
/**
* 功能说明:监控注解
*
* @return <br>
* 1.[2021年09月10日下午13:50] 创建方法 by wheree
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TimeCostRecord {}
其次创建AOP切面
@Component
public class TimeCostRecordAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(TimeCostRecordAspect.class);
// 定义一个切入点
@Pointcut("@annotation(com.wheree.common.utils.aop.TimeCostRecord)")
private void timeCostRecordAspect() {}
/**
* 功能说明:TODO
*
* @return <br>
* [2021年09月10日下午13:50] 创建方法 by wheree
* @params
*/
@Around("timeCostRecordAspect()")
public Object recordSystemLog(ProceedingJoinPoint pjp) throws Throwable {
// 方法通知前获取时间,为什么要记录这个时间呢?当然是用来计算模块执行时间的
long start = System.currentTimeMillis();
long end = 0L;
// 拦截的实体类,就是当前正在执行的controller
Object target = pjp.getTarget();
// 拦截的方法名称。当前正在执行的方法
String methodName = pjp.getSignature().getName();
// 拦截的方法参数
Object[] args = pjp.getArgs();
if (null != args && args.length == 1) {
LOGGER.debug(
"target:{} method: {} 调用的参数是 {} ",
target,
methodName,
JsonUtils.obj2json(args[0]));
}
// 拦截的放参数类型
Signature sig = pjp.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw ServiceException.buildInternalException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes();
Object object = null;
// 获得被拦截的方法
Method method = null;
try {
method = target.getClass().getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
LOGGER.error("recordSystemLog error {}", e1);
} catch (SecurityException e1) {
// TODO Auto-generated catch block
LOGGER.error("recordSystemLog error {}", e1);
}
if (null != method) {
// 判断是否包含自定义的注解,说明一下这里的SystemLog就是我自己自定义的注解
if (method.isAnnotationPresent(TimeCostRecord.class)) {
TimeCostRecord systemLogger = method.getAnnotation(TimeCostRecord.class);
try {
object = pjp.proceed();
} catch (Throwable e) {
LOGGER.error("method proceed error", e);
LOGGER.error("method {} param {}", methodName, JsonUtils.obj2json(args));
throw e;
} finally {
end = System.currentTimeMillis();
// TODO: 2021/9/28 日志记载
LOGGER.debug(
"target:{} method: {} cost {} ms", target, methodName, (end - start));
//TODO 如有需要可在此执行持久化操作
}
} else { // 没有包含注解
object = pjp.proceed();
}
} else { // 不需要拦截直接执行
object = pjp.proceed();
}
LOGGER.debug(
"target:{} method: {} 执行的结果是:{}", target, methodName, JsonUtils.obj2json(object));
return object;
}
最后添加在需要监控的方法上
@TimeCostRecord
@Override
public BaseResult test(TestModel model) {
//dosomethings
}