|
|
@ -28,12 +28,12 @@ import java.lang.annotation.Annotation;
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
|
import java.util.Date;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static com.xjs.consts.ApiConst.DEMOTE_ERROR;
|
|
|
|
import static com.xjs.consts.ApiConst.DEMOTE_ERROR;
|
|
|
|
import static com.xjs.consts.ApiWarnHandleConst.NO;
|
|
|
|
import static com.xjs.consts.ApiWarnHandleConst.NO;
|
|
|
|
|
|
|
|
import static com.xjs.consts.ReqConst.ERROR;
|
|
|
|
|
|
|
|
import static com.xjs.consts.ReqConst.SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* api日志切面类
|
|
|
|
* api日志切面类
|
|
|
@ -76,14 +76,19 @@ public class ApiLogAspect {
|
|
|
|
//执行预警切入逻辑(降级不预警)
|
|
|
|
//执行预警切入逻辑(降级不预警)
|
|
|
|
if (obj instanceof JSONObject) {
|
|
|
|
if (obj instanceof JSONObject) {
|
|
|
|
JSONObject jsonObject = (JSONObject) obj;
|
|
|
|
JSONObject jsonObject = (JSONObject) obj;
|
|
|
|
|
|
|
|
|
|
|
|
if (!jsonObject.containsKey(DEMOTE_ERROR)) {
|
|
|
|
if (!jsonObject.containsKey(DEMOTE_ERROR)) {
|
|
|
|
warning(between, joinPoint);
|
|
|
|
this.warning(between, joinPoint);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
//如果降级,接口状态修改为异常
|
|
|
|
|
|
|
|
this.demoteHandle(joinPoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//返回值为String情况
|
|
|
|
//返回值为String情况
|
|
|
|
if (obj instanceof String) {
|
|
|
|
if (obj instanceof String) {
|
|
|
|
if (StringUtils.isNotEmpty(String.valueOf(obj))) {
|
|
|
|
if (StringUtils.isNotEmpty(String.valueOf(obj))) {
|
|
|
|
warning(between, joinPoint);
|
|
|
|
this.warning(between, joinPoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -94,6 +99,7 @@ public class ApiLogAspect {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 处理完请求后执行
|
|
|
|
* 处理完请求后执行
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -148,11 +154,12 @@ public class ApiLogAspect {
|
|
|
|
if (e != null || StringUtils.isEmpty(response)) {
|
|
|
|
if (e != null || StringUtils.isEmpty(response)) {
|
|
|
|
entity.setIsSuccess(ReqConst.ERROR);
|
|
|
|
entity.setIsSuccess(ReqConst.ERROR);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
entity.setIsSuccess(ReqConst.SUCCESS);
|
|
|
|
entity.setIsSuccess(SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
remoteLogFeign.saveApiLog(entity);
|
|
|
|
remoteLogFeign.saveApiLog(entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 预警切入
|
|
|
|
* 预警切入
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -160,85 +167,145 @@ public class ApiLogAspect {
|
|
|
|
* @param joinPoint aop连接对象
|
|
|
|
* @param joinPoint aop连接对象
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private void warning(long between, ProceedingJoinPoint joinPoint) {
|
|
|
|
private void warning(long between, ProceedingJoinPoint joinPoint) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Map<String, String> annotationInfo = this.getAnnotationInfo(joinPoint);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (CollUtil.isEmpty(annotationInfo)) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String name = annotationInfo.get("name");
|
|
|
|
|
|
|
|
String url = annotationInfo.get("url");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//根据拿到的url和name查询数据库是否存在,存在则count+1,不存在则add
|
|
|
|
|
|
|
|
ApiRecord apiRecord = new ApiRecord();
|
|
|
|
|
|
|
|
apiRecord.setApiName(name);
|
|
|
|
|
|
|
|
apiRecord.setApiUrl(url);
|
|
|
|
|
|
|
|
apiRecord.setRequestTime((int) between);
|
|
|
|
|
|
|
|
R<List<ApiRecord>> listR = remoteWarningCRUDFeign.selectApiRecordListForRPC(apiRecord);
|
|
|
|
|
|
|
|
if (listR.getCode() == R.SUCCESS) {
|
|
|
|
|
|
|
|
List<ApiRecord> data = listR.getData();
|
|
|
|
|
|
|
|
if (CollUtil.isEmpty(data)) {
|
|
|
|
|
|
|
|
//设置初始请求次数
|
|
|
|
|
|
|
|
apiRecord.setTotalCount(1L);
|
|
|
|
|
|
|
|
apiRecord.setDayCount(1L);
|
|
|
|
|
|
|
|
apiRecord.setLimitCount(30L);
|
|
|
|
|
|
|
|
apiRecord.setStatus(SUCCESS);
|
|
|
|
|
|
|
|
remoteWarningCRUDFeign.saveApiRecordForRPC(apiRecord);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ApiRecord haveApiRecord = data.get(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
haveApiRecord.setStatus(SUCCESS);
|
|
|
|
|
|
|
|
haveApiRecord.setRequestTime((int) between);
|
|
|
|
|
|
|
|
haveApiRecord.setTotalCount(haveApiRecord.getTotalCount() + 1L);
|
|
|
|
|
|
|
|
//统计当前的请求次数,隔天清零
|
|
|
|
|
|
|
|
haveApiRecord.setDayCount(haveApiRecord.getDayCount() + 1L);
|
|
|
|
|
|
|
|
Date updateTime = haveApiRecord.getUpdateTime();
|
|
|
|
|
|
|
|
String dateTime = DateUtil.formatDateTime(updateTime);
|
|
|
|
|
|
|
|
Date date = DateUtil.parseDate(dateTime).toJdkDate();
|
|
|
|
|
|
|
|
//当前时间和最后一次修改时间间隔天数(超过1 就清零)
|
|
|
|
|
|
|
|
long compareTime = DateUtil.between(date, new Date(), DateUnit.DAY);
|
|
|
|
|
|
|
|
if (compareTime > 0) {
|
|
|
|
|
|
|
|
haveApiRecord.setDayCount(1L);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//置为空让mp自动填充
|
|
|
|
|
|
|
|
haveApiRecord.setUpdateTime(null);
|
|
|
|
|
|
|
|
remoteWarningCRUDFeign.updateApiRecordForRPC(haveApiRecord);
|
|
|
|
|
|
|
|
//判断接口请求是否超过阈值
|
|
|
|
|
|
|
|
if (Objects.nonNull(haveApiRecord.getLimitCount())) {
|
|
|
|
|
|
|
|
if (haveApiRecord.getDayCount() > haveApiRecord.getLimitCount()) {
|
|
|
|
|
|
|
|
//把记录添加到预警表中
|
|
|
|
|
|
|
|
ApiWarning apiWarning = new ApiWarning();
|
|
|
|
|
|
|
|
apiWarning.setLimitValue(String.valueOf(haveApiRecord.getLimitCount()));
|
|
|
|
|
|
|
|
apiWarning.setRealValue(String.valueOf(haveApiRecord.getDayCount()));
|
|
|
|
|
|
|
|
apiWarning.setApiName(haveApiRecord.getApiName());
|
|
|
|
|
|
|
|
apiWarning.setHandle(NO);
|
|
|
|
|
|
|
|
apiWarning.setWarningLevel(WarnLevelEnum.NOEMAL.getMessage());
|
|
|
|
|
|
|
|
if (haveApiRecord.getDayCount() > haveApiRecord.getLimitCount() * 2 &&
|
|
|
|
|
|
|
|
haveApiRecord.getDayCount() < haveApiRecord.getLimitCount() * 3) {
|
|
|
|
|
|
|
|
apiWarning.setWarningLevel(WarnLevelEnum.WARNING.getMessage());
|
|
|
|
|
|
|
|
} else if (haveApiRecord.getDayCount() > haveApiRecord.getLimitCount() * 3) {
|
|
|
|
|
|
|
|
apiWarning.setWarningLevel(WarnLevelEnum.DANGER.getMessage());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
apiWarning.setWarningType(WarnTypeEnum.API.getType());
|
|
|
|
|
|
|
|
String message = String.format(WarnTypeEnum.API.getMessage(),
|
|
|
|
|
|
|
|
haveApiRecord.getApiName(),
|
|
|
|
|
|
|
|
haveApiRecord.getLimitCount(),
|
|
|
|
|
|
|
|
haveApiRecord.getDayCount());
|
|
|
|
|
|
|
|
apiWarning.setWarningMessage(message);
|
|
|
|
|
|
|
|
remoteWarningCRUDFeign.saveApiWarningForRPC(apiWarning);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 接口降级修改状态异常
|
|
|
|
|
|
|
|
* @param joinPoint 切入点
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private void demoteHandle(ProceedingJoinPoint joinPoint) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Map<String, String> map = this.getAnnotationInfo(joinPoint);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (CollUtil.isEmpty(map)) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String name = map.get("name");
|
|
|
|
|
|
|
|
String url = map.get("url");
|
|
|
|
|
|
|
|
ApiRecord apiRecord = new ApiRecord();
|
|
|
|
|
|
|
|
apiRecord.setApiName(name);
|
|
|
|
|
|
|
|
apiRecord.setApiUrl(url);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
R<List<ApiRecord>> listR = remoteWarningCRUDFeign.selectApiRecordListForRPC(apiRecord);
|
|
|
|
|
|
|
|
if (listR.getCode() == R.SUCCESS) {
|
|
|
|
|
|
|
|
List<ApiRecord> data = listR.getData();
|
|
|
|
|
|
|
|
if (CollUtil.isNotEmpty(data)) {
|
|
|
|
|
|
|
|
ApiRecord haveApiRecord = data.get(0);
|
|
|
|
|
|
|
|
//置为空让mp自动填充
|
|
|
|
|
|
|
|
haveApiRecord.setUpdateTime(null);
|
|
|
|
|
|
|
|
haveApiRecord.setStatus(ERROR);
|
|
|
|
|
|
|
|
remoteWarningCRUDFeign.updateApiRecordForRPC(haveApiRecord);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 通过反射获取注解信息
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param joinPoint 切入点
|
|
|
|
|
|
|
|
* @return 注解信息map
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private Map<String, String> getAnnotationInfo(ProceedingJoinPoint joinPoint) {
|
|
|
|
//获取目标类名及方法名
|
|
|
|
//获取目标类名及方法名
|
|
|
|
Signature signature = joinPoint.getSignature();
|
|
|
|
Signature signature = joinPoint.getSignature();
|
|
|
|
String method = signature.getName();
|
|
|
|
String method = signature.getName();
|
|
|
|
Class aclass = signature.getDeclaringType();
|
|
|
|
Class aclass = signature.getDeclaringType();
|
|
|
|
Method[] methods = aclass.getMethods();
|
|
|
|
Method[] methods = aclass.getMethods();
|
|
|
|
|
|
|
|
|
|
|
|
//根据目标的方法名判断当前方法
|
|
|
|
//根据目标的方法名判断当前方法
|
|
|
|
for (Method thisMethod : methods) {
|
|
|
|
for (Method thisMethod : methods) {
|
|
|
|
if (method.equals(thisMethod.getName())) {
|
|
|
|
if (method.equals(thisMethod.getName())) {
|
|
|
|
|
|
|
|
|
|
|
|
//拿到当前方法的注解判断是否为apiLog注解
|
|
|
|
//拿到当前方法的注解判断是否为apiLog注解
|
|
|
|
Annotation[] declaredAnnotations = thisMethod.getDeclaredAnnotations();
|
|
|
|
Annotation[] declaredAnnotations = thisMethod.getDeclaredAnnotations();
|
|
|
|
|
|
|
|
|
|
|
|
for (Annotation annotation : declaredAnnotations) {
|
|
|
|
for (Annotation annotation : declaredAnnotations) {
|
|
|
|
if (annotation instanceof ApiLog) {
|
|
|
|
if (annotation instanceof ApiLog) {
|
|
|
|
String name = ((ApiLog) annotation).name();
|
|
|
|
String name = ((ApiLog) annotation).name();
|
|
|
|
String url = ((ApiLog) annotation).url();
|
|
|
|
String url = ((ApiLog) annotation).url();
|
|
|
|
//根据拿到的url和name查询数据库是否存在,存在则count+1,不存在则add
|
|
|
|
|
|
|
|
ApiRecord apiRecord = new ApiRecord();
|
|
|
|
Map<String, String> hashMap = new HashMap<>();
|
|
|
|
apiRecord.setApiName(name);
|
|
|
|
hashMap.put("name", name);
|
|
|
|
apiRecord.setApiUrl(url);
|
|
|
|
hashMap.put("url", url);
|
|
|
|
apiRecord.setRequestTime((int) between);
|
|
|
|
return hashMap;
|
|
|
|
R<List<ApiRecord>> listR = remoteWarningCRUDFeign.selectApiRecordListForRPC(apiRecord);
|
|
|
|
|
|
|
|
if (listR.getCode() == R.SUCCESS) {
|
|
|
|
|
|
|
|
List<ApiRecord> data = listR.getData();
|
|
|
|
|
|
|
|
if (CollUtil.isEmpty(data)) {
|
|
|
|
|
|
|
|
//设置初始请求次数
|
|
|
|
|
|
|
|
apiRecord.setTotalCount(1L);
|
|
|
|
|
|
|
|
apiRecord.setDayCount(1L);
|
|
|
|
|
|
|
|
apiRecord.setLimitCount(30L);
|
|
|
|
|
|
|
|
remoteWarningCRUDFeign.saveApiRecordForRPC(apiRecord);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ApiRecord haveApiRecord = data.get(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
haveApiRecord.setRequestTime((int) between);
|
|
|
|
|
|
|
|
haveApiRecord.setTotalCount(haveApiRecord.getTotalCount() + 1L);
|
|
|
|
|
|
|
|
//统计当前的请求次数,隔天清零
|
|
|
|
|
|
|
|
haveApiRecord.setDayCount(haveApiRecord.getDayCount() + 1L);
|
|
|
|
|
|
|
|
Date updateTime = haveApiRecord.getUpdateTime();
|
|
|
|
|
|
|
|
String dateTime = DateUtil.formatDateTime(updateTime);
|
|
|
|
|
|
|
|
Date date = DateUtil.parseDate(dateTime).toJdkDate();
|
|
|
|
|
|
|
|
//当前时间和最后一次修改时间间隔天数(超过1 就清零)
|
|
|
|
|
|
|
|
long compareTime = DateUtil.between(date, new Date(), DateUnit.DAY);
|
|
|
|
|
|
|
|
if (compareTime > 0) {
|
|
|
|
|
|
|
|
haveApiRecord.setDayCount(1L);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//置为空让mp自动填充
|
|
|
|
|
|
|
|
haveApiRecord.setUpdateTime(null);
|
|
|
|
|
|
|
|
remoteWarningCRUDFeign.updateApiRecordForRPC(haveApiRecord);
|
|
|
|
|
|
|
|
//判断接口请求是否超过阈值
|
|
|
|
|
|
|
|
if (Objects.nonNull(haveApiRecord.getLimitCount())) {
|
|
|
|
|
|
|
|
if (haveApiRecord.getDayCount() > haveApiRecord.getLimitCount()) {
|
|
|
|
|
|
|
|
//把记录添加到预警表中
|
|
|
|
|
|
|
|
ApiWarning apiWarning = new ApiWarning();
|
|
|
|
|
|
|
|
apiWarning.setLimitValue(String.valueOf(haveApiRecord.getLimitCount()));
|
|
|
|
|
|
|
|
apiWarning.setRealValue(String.valueOf(haveApiRecord.getDayCount()));
|
|
|
|
|
|
|
|
apiWarning.setApiName(haveApiRecord.getApiName());
|
|
|
|
|
|
|
|
apiWarning.setHandle(NO);
|
|
|
|
|
|
|
|
apiWarning.setWarningLevel(WarnLevelEnum.NOEMAL.getMessage());
|
|
|
|
|
|
|
|
if (haveApiRecord.getDayCount() > haveApiRecord.getLimitCount() * 2 &&
|
|
|
|
|
|
|
|
haveApiRecord.getDayCount() < haveApiRecord.getLimitCount() * 3) {
|
|
|
|
|
|
|
|
apiWarning.setWarningLevel(WarnLevelEnum.WARNING.getMessage());
|
|
|
|
|
|
|
|
} else if (haveApiRecord.getDayCount() > haveApiRecord.getLimitCount() * 3) {
|
|
|
|
|
|
|
|
apiWarning.setWarningLevel(WarnLevelEnum.DANGER.getMessage());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
apiWarning.setWarningType(WarnTypeEnum.API.getType());
|
|
|
|
|
|
|
|
String message = String.format(WarnTypeEnum.API.getMessage(),
|
|
|
|
|
|
|
|
haveApiRecord.getApiName(),
|
|
|
|
|
|
|
|
haveApiRecord.getLimitCount(),
|
|
|
|
|
|
|
|
haveApiRecord.getDayCount());
|
|
|
|
|
|
|
|
apiWarning.setWarningMessage(message);
|
|
|
|
|
|
|
|
remoteWarningCRUDFeign.saveApiWarningForRPC(apiWarning);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|