mirror of
https://gitee.com/huoyo/ko-time.git
synced 2025-12-06 16:58:26 +08:00
477 lines
22 KiB
Java
477 lines
22 KiB
Java
package cn.langpy.kotime.data;
|
|
|
|
import cn.langpy.kotime.constant.KoSqlConstant;
|
|
import cn.langpy.kotime.model.*;
|
|
import cn.langpy.kotime.service.GraphService;
|
|
import cn.langpy.kotime.util.Common;
|
|
import cn.langpy.kotime.util.Context;
|
|
import cn.langpy.kotime.util.DataBaseUtil;
|
|
import cn.langpy.kotime.util.MethodType;
|
|
import org.springframework.context.annotation.Lazy;
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import java.lang.reflect.Parameter;
|
|
import java.math.BigDecimal;
|
|
import java.sql.Connection;
|
|
import java.sql.SQLException;
|
|
import java.util.*;
|
|
import java.util.logging.Logger;
|
|
import java.util.stream.Collectors;
|
|
|
|
import static java.util.stream.Collectors.toList;
|
|
|
|
/**
|
|
* zhangchang
|
|
*/
|
|
@Component("database")
|
|
@Lazy
|
|
public class DataBase implements GraphService {
|
|
public static Logger log = Logger.getLogger(DataBase.class.toString());
|
|
|
|
private Connection readConnection;
|
|
private Connection writeConnection;
|
|
|
|
public DataBase() {
|
|
Runtime.getRuntime().addShutdownHook(
|
|
new Thread(() -> {
|
|
try {
|
|
log.info("kotime=>close database connections...");
|
|
if (null!=readConnection) {
|
|
readConnection.close();
|
|
}
|
|
if (null!=writeConnection) {
|
|
writeConnection.close();
|
|
}
|
|
} catch (SQLException throwables) {
|
|
throwables.printStackTrace();
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
public Connection getReadConnection() {
|
|
try {
|
|
if (null == readConnection || readConnection.isClosed()) {
|
|
readConnection = Context.getDataSource().getConnection();
|
|
}
|
|
} catch (SQLException throwables) {
|
|
throwables.printStackTrace();
|
|
}
|
|
|
|
return readConnection;
|
|
}
|
|
|
|
public Connection getWriteConnection() {
|
|
try {
|
|
if (null == writeConnection || writeConnection.isClosed()) {
|
|
writeConnection = Context.getDataSource().getConnection();
|
|
}
|
|
} catch (SQLException throwables) {
|
|
throwables.printStackTrace();
|
|
}
|
|
return writeConnection;
|
|
}
|
|
|
|
@Override
|
|
public void addMethodNode(MethodNode methodNode) {
|
|
if (null == methodNode) {
|
|
return;
|
|
}
|
|
List<Map<String, Object>> query = DataBaseUtil.query(getWriteConnection(),KoSqlConstant.queryMethod, new Object[]{methodNode.getId()});
|
|
if (query.size() == 0) {
|
|
Object[] params = new Object[]{
|
|
methodNode.getId(),
|
|
methodNode.getName(),
|
|
methodNode.getClassName(),
|
|
methodNode.getMethodName(),
|
|
methodNode.getRouteName(),
|
|
methodNode.getMethodType().name()
|
|
};
|
|
DataBaseUtil.insert(getWriteConnection(),KoSqlConstant.addMethod, params);
|
|
} else {
|
|
if (methodNode.getMethodType() == MethodType.Controller && !StringUtils.isEmpty(methodNode.getRouteName())) {
|
|
Object[] params = new Object[]{
|
|
methodNode.getName(),
|
|
methodNode.getClassName(),
|
|
methodNode.getMethodName(),
|
|
methodNode.getRouteName(),
|
|
methodNode.getMethodType().name(),
|
|
methodNode.getId(),
|
|
};
|
|
DataBaseUtil.update(getWriteConnection(),KoSqlConstant.updateMethod, params);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
public synchronized void addExceptionNode(ExceptionNode exceptionNode) {
|
|
List<Map<String, Object>> query = DataBaseUtil.query(getWriteConnection(),KoSqlConstant.queryException, new Object[]{exceptionNode.getId()});
|
|
if (query.size() == 0) {
|
|
Object[] params = new Object[]{
|
|
exceptionNode.getId(),
|
|
exceptionNode.getName(),
|
|
exceptionNode.getClassName(),
|
|
exceptionNode.getMessage()
|
|
};
|
|
DataBaseUtil.insert(getWriteConnection(),KoSqlConstant.addException, params);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
public synchronized MethodRelation addMethodRelation(MethodNode sourceMethodNode, MethodNode targetMethodNode) {
|
|
if (null == sourceMethodNode || null == targetMethodNode) {
|
|
return null;
|
|
}
|
|
if (sourceMethodNode.getId().equals(targetMethodNode.getId())) {
|
|
return null;
|
|
}
|
|
try {
|
|
List<Map<String, Object>> query = DataBaseUtil.query(getWriteConnection(),KoSqlConstant.queryMethodRe, new Object[]{sourceMethodNode.getId() + targetMethodNode.getId()});
|
|
if (query.size() > 0) {
|
|
Map<String, Object> old = query.get(0);
|
|
double oldAvg = Double.valueOf(old.get("avg_run_time") + "");
|
|
double oldMax = Double.valueOf(old.get("max_run_time") + "");
|
|
double oldMin = Double.valueOf(old.get("min_run_time") + "");
|
|
BigDecimal bg = BigDecimal.valueOf((targetMethodNode.getValue() + oldAvg) / 2.0);
|
|
double avg = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
|
double max = targetMethodNode.getValue() > oldMax ? targetMethodNode.getValue() : oldMax;
|
|
double min = targetMethodNode.getValue() < oldMin ? targetMethodNode.getValue() : oldMin;
|
|
Object[] params = new Object[]{
|
|
sourceMethodNode.getId(),
|
|
targetMethodNode.getId(),
|
|
avg,
|
|
max,
|
|
min,
|
|
sourceMethodNode.getId() + targetMethodNode.getId()
|
|
};
|
|
DataBaseUtil.update(getWriteConnection(),KoSqlConstant.updateMethodRe, params);
|
|
return null;
|
|
} else {
|
|
Object[] params = new Object[]{
|
|
sourceMethodNode.getId() + targetMethodNode.getId(),
|
|
sourceMethodNode.getId(),
|
|
targetMethodNode.getId(),
|
|
targetMethodNode.getValue(),
|
|
targetMethodNode.getValue(),
|
|
targetMethodNode.getValue()
|
|
};
|
|
DataBaseUtil.insert(getWriteConnection(),KoSqlConstant.addMethodRe, params);
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public synchronized ExceptionRelation addExceptionRelation(MethodNode sourceMethodNode, ExceptionNode exceptionNode) {
|
|
List<Map<String, Object>> query = DataBaseUtil.query(getWriteConnection(),KoSqlConstant.queryExceptionRe, new Object[]{sourceMethodNode.getId() + exceptionNode.getId()});
|
|
if (query.size() == 0) {
|
|
Object[] params = new Object[]{
|
|
sourceMethodNode.getId() + exceptionNode.getId(),
|
|
sourceMethodNode.getId(),
|
|
exceptionNode.getId(),
|
|
exceptionNode.getValue()
|
|
};
|
|
DataBaseUtil.insert(getWriteConnection(),KoSqlConstant.addExceptionRe, params);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public synchronized void addParamAnalyse(String methodId, Parameter[] names, Object[] values, double v) {
|
|
String paramsKey = Common.getPramsStr(names, values);
|
|
List<Map<String, Object>> query = DataBaseUtil.query(getWriteConnection(),KoSqlConstant.queryParamsAna, new Object[]{methodId, paramsKey});
|
|
if (query.size() == 0) {
|
|
Object[] params = new Object[]{
|
|
methodId,
|
|
paramsKey,
|
|
v,
|
|
v,
|
|
v
|
|
};
|
|
DataBaseUtil.insert(getWriteConnection(),KoSqlConstant.addParamsAna, params);
|
|
} else {
|
|
Map<String, Object> old = query.get(0);
|
|
double oldAvg = Double.valueOf(old.get("avg_run_time") + "");
|
|
double oldMax = Double.valueOf(old.get("max_run_time") + "");
|
|
double oldMin = Double.valueOf(old.get("min_run_time") + "");
|
|
BigDecimal bg = BigDecimal.valueOf((v + oldAvg) / 2.0);
|
|
double avg = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
|
double max = v > oldMax ? v : oldMax;
|
|
double min = v < oldMin ? v : oldMin;
|
|
Object[] params = new Object[]{
|
|
avg,
|
|
max,
|
|
min,
|
|
methodId,
|
|
paramsKey
|
|
};
|
|
DataBaseUtil.update(getWriteConnection(),KoSqlConstant.updateParamsAna, params);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public MethodInfo getTree(String methodId) {
|
|
MethodInfo rootInfo = new MethodInfo();
|
|
List<MethodNode> methodNodes = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethod, new Object[]{methodId}, MethodNode.class);
|
|
if (methodNodes.size() == 0) {
|
|
return rootInfo;
|
|
}
|
|
|
|
MethodNode methodNode = methodNodes.get(0);
|
|
rootInfo.setId(methodNode.getId());
|
|
rootInfo.setName(methodNode.getName());
|
|
rootInfo.setClassName(methodNode.getClassName());
|
|
rootInfo.setMethodName(methodNode.getMethodName());
|
|
rootInfo.setMethodType(methodNode.getMethodType());
|
|
rootInfo.setRouteName(methodNode.getRouteName());
|
|
|
|
List<MethodRelation> relations = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethodReByTarget, new Object[]{methodId}, MethodRelation.class);
|
|
if (relations.size() == 0) {
|
|
return rootInfo;
|
|
}
|
|
MethodRelation methodRelation = relations.get(0);
|
|
|
|
rootInfo.setValue(methodRelation.getAvgRunTime());
|
|
rootInfo.setAvgRunTime(methodRelation.getAvgRunTime());
|
|
rootInfo.setMaxRunTime(methodRelation.getMaxRunTime());
|
|
rootInfo.setMinRunTime(methodRelation.getMinRunTime());
|
|
List<ExceptionInfo> exceptionInfos = getExceptions(methodId);
|
|
rootInfo.setExceptionNum(exceptionInfos.size());
|
|
rootInfo.setExceptions(exceptionInfos);
|
|
List<String> methodInfos = new ArrayList<>();
|
|
recursionMethod(rootInfo, methodInfos);
|
|
methodInfos.clear();
|
|
return rootInfo;
|
|
}
|
|
|
|
public void recursionMethod(MethodInfo rootInfo, List<String> methodInfos) {
|
|
List<MethodInfo> children = getChildren(rootInfo.getId());
|
|
if (children != null && children.size() > 0) {
|
|
if (!methodInfos.contains(rootInfo.getId())) {
|
|
methodInfos.add(rootInfo.getId());
|
|
rootInfo.setChildren(children);
|
|
for (MethodInfo child : children) {
|
|
recursionMethod(child, methodInfos);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public Map<String, ParamMetric> getMethodParamGraph(String methodId) {
|
|
Map<String, ParamMetric> paramMetricMap = new HashMap<>();
|
|
List<ParamAna> paramAnas = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryParamsAnaBySource, new Object[]{methodId}, ParamAna.class);
|
|
|
|
if (paramAnas.size() == 0) {
|
|
return paramMetricMap;
|
|
}
|
|
for (ParamAna paramAna : paramAnas) {
|
|
if (!paramMetricMap.containsKey(paramAna.getSourceId())) {
|
|
ParamMetric paramMetric = new ParamMetric();
|
|
paramMetric.setAvgRunTime(paramAna.getAvgRunTime());
|
|
paramMetric.setMaxRunTime(paramAna.getMaxRunTime());
|
|
paramMetric.setMinRunTime(paramAna.getMinRunTime());
|
|
paramMetricMap.put(paramAna.getParams(), paramMetric);
|
|
}
|
|
}
|
|
return paramMetricMap;
|
|
}
|
|
|
|
@Override
|
|
public SystemStatistic getRunStatistic() {
|
|
SystemStatistic systemStatistic = new SystemStatistic();
|
|
List<MethodInfo> controllerApis = getControllers();
|
|
if (null == controllerApis || controllerApis.size() == 0) {
|
|
return systemStatistic;
|
|
}
|
|
int delayNum = (int) controllerApis.stream().filter(controllerApi -> controllerApi.getAvgRunTime() >= Context.getConfig().getThreshold()).count();
|
|
systemStatistic.setDelayNum(delayNum);
|
|
int normalNum = (int) controllerApis.stream().filter(controllerApi -> controllerApi.getAvgRunTime() < Context.getConfig().getThreshold()).count();
|
|
systemStatistic.setNormalNum(normalNum);
|
|
int totalNum = (int) controllerApis.stream().count();
|
|
systemStatistic.setTotalNum(totalNum);
|
|
Double max = controllerApis.stream().map(api -> api.getAvgRunTime()).max(Double::compareTo).get();
|
|
Double min = controllerApis.stream().map(api -> api.getAvgRunTime()).min(Double::compareTo).get();
|
|
Double avg = controllerApis.stream().map(api -> api.getAvgRunTime()).collect(Collectors.averagingDouble(Double::doubleValue));
|
|
BigDecimal bg = BigDecimal.valueOf(avg);
|
|
avg = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
|
systemStatistic.setMaxRunTime(max);
|
|
systemStatistic.setMinRunTime(min);
|
|
systemStatistic.setAvgRunTime(avg);
|
|
return systemStatistic;
|
|
}
|
|
|
|
@Override
|
|
public List<MethodInfo> getControllers() {
|
|
List<MethodInfo> methodInfos = new ArrayList<>();
|
|
List<MethodInfo> controllers = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryController, new Object[]{MethodType.Controller.name()}, MethodInfo.class);
|
|
for (MethodInfo methodNode : controllers) {
|
|
String id = methodNode.getId();
|
|
List<MethodRelation> relations = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethodReByTarget, new Object[]{id}, MethodRelation.class);
|
|
if (relations.size() == 0) {
|
|
continue;
|
|
}
|
|
MethodRelation relation = relations.get(0);
|
|
MethodInfo methodInfo = new MethodInfo();
|
|
methodInfo.setId(methodNode.getId());
|
|
methodInfo.setName(methodNode.getName());
|
|
methodInfo.setClassName(methodNode.getClassName());
|
|
methodInfo.setMethodName(methodNode.getMethodName());
|
|
methodInfo.setMethodType(methodNode.getMethodType());
|
|
methodInfo.setRouteName(methodNode.getRouteName());
|
|
methodInfo.setValue(relation.getAvgRunTime());
|
|
methodInfo.setAvgRunTime(relation.getAvgRunTime());
|
|
methodInfo.setMaxRunTime(relation.getMaxRunTime());
|
|
methodInfo.setMinRunTime(relation.getMinRunTime());
|
|
if (!methodInfos.contains(methodInfo)) {
|
|
methodInfos.add(methodInfo);
|
|
}
|
|
}
|
|
return methodInfos;
|
|
}
|
|
|
|
@Override
|
|
public List<String> getCondidates(String question) {
|
|
List<MethodNode> methodNodes = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethodLikeName, new Object[]{"%" + question + "%"}, MethodNode.class);
|
|
List<String> methodInfos = new ArrayList<>();
|
|
if (methodNodes.size() > 0) {
|
|
methodInfos = methodNodes.stream().map(MethodNode::getName).collect(toList());
|
|
}
|
|
return methodInfos;
|
|
}
|
|
|
|
@Override
|
|
public List<MethodInfo> searchMethods(String question) {
|
|
List<MethodInfo> methodInfos = new ArrayList<>();
|
|
List<MethodNode> methodNodes = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethodLikeName, new Object[]{"%" + question + "%"}, MethodNode.class);
|
|
for (MethodNode methodNode : methodNodes) {
|
|
String id = methodNode.getId();
|
|
List<MethodRelation> relations = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethodReByTarget, new Object[]{id}, MethodRelation.class);
|
|
if (relations.size() == 0) {
|
|
continue;
|
|
}
|
|
MethodRelation relation = relations.get(0);
|
|
MethodInfo methodInfo = new MethodInfo();
|
|
methodInfo.setId(methodNode.getId());
|
|
methodInfo.setName(methodNode.getName());
|
|
methodInfo.setClassName(methodNode.getClassName());
|
|
methodInfo.setMethodName(methodNode.getMethodName());
|
|
methodInfo.setMethodType(methodNode.getMethodType());
|
|
methodInfo.setRouteName(methodNode.getRouteName());
|
|
methodInfo.setValue(relation.getAvgRunTime());
|
|
methodInfo.setAvgRunTime(relation.getAvgRunTime());
|
|
methodInfo.setMaxRunTime(relation.getMaxRunTime());
|
|
methodInfo.setMinRunTime(relation.getMinRunTime());
|
|
if (!methodInfos.contains(methodInfo)) {
|
|
methodInfos.add(methodInfo);
|
|
}
|
|
}
|
|
return methodInfos;
|
|
}
|
|
|
|
@Override
|
|
public List<MethodInfo> getChildren(String methodId) {
|
|
|
|
List<MethodRelation> relations = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethodReBySource, new Object[]{methodId}, MethodRelation.class);
|
|
|
|
List<MethodInfo> methodInfos = new ArrayList<>();
|
|
for (MethodRelation methodRelation : relations) {
|
|
List<MethodNode> methodNodes = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethod, new Object[]{methodRelation.getTargetId()}, MethodNode.class);
|
|
if (methodNodes.size() == 0) {
|
|
continue;
|
|
}
|
|
MethodNode methodNode = methodNodes.get(0);
|
|
MethodInfo methodInfo = new MethodInfo();
|
|
methodInfo.setId(methodNode.getId());
|
|
methodInfo.setName(methodNode.getName());
|
|
methodInfo.setClassName(methodNode.getClassName());
|
|
methodInfo.setMethodName(methodNode.getMethodName());
|
|
methodInfo.setRouteName(methodNode.getRouteName());
|
|
methodInfo.setMethodType(methodNode.getMethodType());
|
|
methodInfo.setValue(methodRelation.getAvgRunTime());
|
|
methodInfo.setAvgRunTime(methodRelation.getAvgRunTime());
|
|
methodInfo.setMaxRunTime(methodRelation.getMaxRunTime());
|
|
methodInfo.setMinRunTime(methodRelation.getMinRunTime());
|
|
|
|
List<ExceptionInfo> exceptionInfos = getExceptions(methodNode.getId());
|
|
methodInfo.setExceptionNum(exceptionInfos.size());
|
|
methodInfo.setExceptions(exceptionInfos);
|
|
if (!methodInfos.contains(methodInfo)) {
|
|
methodInfos.add(methodInfo);
|
|
}
|
|
}
|
|
return methodInfos;
|
|
}
|
|
|
|
@Override
|
|
public List<ExceptionInfo> getExceptionInfos(String exceptionId) {
|
|
List<ExceptionRelation> relations = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryExceptionReByTarget, new Object[]{exceptionId}, ExceptionRelation.class);
|
|
List<ExceptionInfo> exceptionInfos = new ArrayList<>();
|
|
for (ExceptionRelation relation : relations) {
|
|
String sourceMethodId = relation.getSourceId();
|
|
List<MethodNode> methodNodes = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethod, new Object[]{sourceMethodId}, MethodNode.class);
|
|
if (methodNodes.size() == 0) {
|
|
continue;
|
|
}
|
|
MethodNode methodNode = methodNodes.get(0);
|
|
|
|
List<ExceptionNode> exceptions = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryMethod, new Object[]{exceptionId}, ExceptionNode.class);
|
|
if (methodNodes.size() == 0) {
|
|
continue;
|
|
}
|
|
ExceptionNode exceptionNode = exceptions.get(0);
|
|
ExceptionInfo exceptionInfo = new ExceptionInfo();
|
|
exceptionInfo.setId(exceptionNode.getId());
|
|
exceptionInfo.setName(exceptionNode.getName());
|
|
exceptionInfo.setClassName(exceptionNode.getClassName());
|
|
exceptionInfo.setLocation(relation.getLocation());
|
|
exceptionInfo.setMessage(exceptionNode.getMessage());
|
|
exceptionInfo.setMethodName(methodNode.getMethodName());
|
|
exceptionInfo.setOccurClassName(methodNode.getClassName());
|
|
if (!exceptionInfos.contains(exceptionInfo)) {
|
|
exceptionInfos.add(exceptionInfo);
|
|
}
|
|
}
|
|
return exceptionInfos;
|
|
}
|
|
|
|
@Override
|
|
public List<ExceptionInfo> getExceptions(String methodId) {
|
|
List<ExceptionInfo> exceptionInfos = new ArrayList<>();
|
|
List<ExceptionRelation> relations = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryExceptionReByTarget, new Object[]{methodId}, ExceptionRelation.class);
|
|
for (ExceptionRelation relation : relations) {
|
|
String exceptionId = relation.getTargetId();
|
|
List<ExceptionNode> exceptionNodes = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryException, new Object[]{exceptionId}, ExceptionNode.class);
|
|
if (exceptionNodes.size() == 0) {
|
|
continue;
|
|
}
|
|
ExceptionNode exceptionNode = exceptionNodes.get(0);
|
|
ExceptionInfo exceptionInfo = new ExceptionInfo();
|
|
exceptionInfo.setId(exceptionNode.getId());
|
|
exceptionInfo.setName(exceptionNode.getName());
|
|
exceptionInfo.setClassName(exceptionNode.getClassName());
|
|
exceptionInfo.setMessage(exceptionNode.getMessage());
|
|
exceptionInfo.setLocation(relation.getLocation());
|
|
if (!exceptionInfos.contains(exceptionInfo)) {
|
|
exceptionInfos.add(exceptionInfo);
|
|
}
|
|
}
|
|
return exceptionInfos;
|
|
}
|
|
|
|
@Override
|
|
public List<ExceptionNode> getExceptions() {
|
|
List<ExceptionNode> exceptionNodes = DataBaseUtil.query(getReadConnection(),KoSqlConstant.queryExceptions, null, ExceptionNode.class);
|
|
return exceptionNodes;
|
|
}
|
|
|
|
|
|
}
|