diff --git a/README.md b/README.md
index e4c6a66..c44650f 100644
--- a/README.md
+++ b/README.md
@@ -63,8 +63,9 @@ http://huoyo.gitee.io/ko-time
> V1.8:支持Mybatis的Mapper监测、新增最大/最小运行时间、修复小数位数过长页面边界溢出的bug
-> V1.9:添加异常监测,开放数据接口,修复与swagger冲突bug,添加配置动态更新功能以及重构数据存储机制
+> V1.9:过度版本
+> V2.0.0:添加异常监测,开放数据接口,修复与swagger冲突bug,添加配置动态更新功能以及重构数据存储机制
#### 特别说明
1.本项目使用java8开发,其他版本未曾试验,如有什么bug还请告知!
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
index 3e6c8ae..39ebbe1 100644
--- a/docs/_sidebar.md
+++ b/docs/_sidebar.md
@@ -1,3 +1,5 @@
* [简介](introduce)
* [快速上手](getstart)
+* [UI页面说明](uiguide)
+* [API数据接口](apiintro)
* [常见问题](questions)
\ No newline at end of file
diff --git a/docs/apiintro.md b/docs/apiintro.md
new file mode 100644
index 0000000..1467f2c
--- /dev/null
+++ b/docs/apiintro.md
@@ -0,0 +1,282 @@
+
+## 获取接口方法列表
+
+* 接口名
+
+>`GET` /koTime/getApis
+
+* 返回示例
+
+```json
+[
+ {
+ "id":"com.example.demo.controller.IndexController.test1",
+ "name":"IndexController.test1",
+ "className":"com.example.demo.controller.IndexController",
+ "methodName":"test1",
+ "value":2001.38,
+ "avgRunTime":2001.38,
+ "maxRunTime":2001.9,
+ "minRunTime":2001.19,
+ "methodType":"Controller",
+ "exceptionNum":0,
+ "children":[
+
+ ],
+ "exceptions":[
+
+ ]
+ },
+ {
+ "id":"com.example.demo.controller.IndexController.test2",
+ "name":"IndexController.test1",
+ "className":"com.example.demo.controller.IndexController",
+ "methodName":"test1",
+ "value":2001.38,
+ "avgRunTime":2001.38,
+ "maxRunTime":2001.9,
+ "minRunTime":2001.19,
+ "methodType":"Controller",
+ "exceptionNum":0,
+ "children":[
+
+ ],
+ "exceptions":[
+
+ ]
+ }
+]
+```
+
+
+## 获取方法列表调用链路
+
+* 接口名
+
+>`GET` /koTime/getTree?methodName=每一个方法的id
+
+* 返回示例
+```json
+{
+ "id":"com.example.demo.controller.IndexController.test1",
+ "name":"IndexController.test1",
+ "className":"com.example.demo.controller.IndexController",
+ "methodName":"test1",
+ "value":2001.38,
+ "avgRunTime":2001.38,
+ "maxRunTime":2001.9,
+ "minRunTime":2001.19,
+ "methodType":"Controller",
+ "exceptionNum":0,
+ "children":[
+ {
+ "id":"com.example.demo.service.impl.IndexServiceImpl.getParents",
+ "name":"IndexServiceImpl.getParents",
+ "className":"com.example.demo.service.impl.IndexServiceImpl",
+ "methodName":"getParents",
+ "value":0.47,
+ "avgRunTime":0.47,
+ "maxRunTime":0.59,
+ "minRunTime":0.43,
+ "methodType":"Service",
+ "exceptionNum":1,
+ "children":[
+ {
+ "id":"com.example.demo.service.impl.IndexServiceImpl.index2",
+ "name":"IndexServiceImpl.index2",
+ "className":"com.example.demo.service.impl.IndexServiceImpl",
+ "methodName":"index2",
+ "value":0.35,
+ "avgRunTime":0.35,
+ "maxRunTime":0.4,
+ "minRunTime":0.32,
+ "methodType":"Service",
+ "exceptionNum":0,
+ "children":[
+
+ ],
+ "exceptions":[
+
+ ]
+ }
+ ],
+ "exceptions":[
+ {
+ "id":"java.lang.RuntimeExceptionRuntimeException获取信息失败",
+ "name":"RuntimeException",
+ "className":"java.lang.RuntimeException",
+ "message":"获取信息失败",
+ "location":91,
+ "methodName":null,
+ "occurClassName":null
+ }
+ ]
+ },
+ {
+ "id":"com.example.demo.service.impl.IndexServiceImpl.getUsers",
+ "name":"IndexServiceImpl.getUsers",
+ "className":"com.example.demo.service.impl.IndexServiceImpl",
+ "methodName":"getUsers",
+ "value":1000.91,
+ "avgRunTime":1000.91,
+ "maxRunTime":1006.25,
+ "minRunTime":1000.79,
+ "methodType":"Service",
+ "exceptionNum":1,
+ "children":[
+ {
+ "id":"com.example.demo.service.impl.IndexServiceImpl.index1",
+ "name":"IndexServiceImpl.index1",
+ "className":"com.example.demo.service.impl.IndexServiceImpl",
+ "methodName":"index1",
+ "value":0.42,
+ "avgRunTime":0.42,
+ "maxRunTime":3.81,
+ "minRunTime":0.37,
+ "methodType":"Service",
+ "exceptionNum":0,
+ "children":[
+ {
+ "id":"com.example.demo.service.impl.IndexServiceImpl.test2",
+ "name":"IndexServiceImpl.test2",
+ "className":"com.example.demo.service.impl.IndexServiceImpl",
+ "methodName":"test2",
+ "value":0.01,
+ "avgRunTime":0.01,
+ "maxRunTime":0.02,
+ "minRunTime":"0.0",
+ "methodType":"Service",
+ "exceptionNum":0,
+ "children":[
+
+ ],
+ "exceptions":[
+
+ ]
+ },
+ {
+ "id":"com.example.demo.service.impl.IndexServiceImpl.test1",
+ "name":"IndexServiceImpl.test1",
+ "className":"com.example.demo.service.impl.IndexServiceImpl",
+ "methodName":"test1",
+ "value":0.04,
+ "avgRunTime":0.04,
+ "maxRunTime":0.08,
+ "minRunTime":0.03,
+ "methodType":"Service",
+ "exceptionNum":0,
+ "children":[
+
+ ],
+ "exceptions":[
+
+ ]
+ }
+ ],
+ "exceptions":[
+
+ ]
+ }
+ ],
+ "exceptions":[
+ {
+ "id":"java.lang.RuntimeExceptionRuntimeException认证失败",
+ "name":"RuntimeException",
+ "className":"java.lang.RuntimeException",
+ "message":"认证失败",
+ "location":82,
+ "methodName":null,
+ "occurClassName":null
+ }
+ ]
+ }
+ ],
+ "exceptions":[
+
+ ]
+}
+```
+
+## 获取异常列表
+
+* 接口名
+
+>`GET` /koTime/getExceptions
+
+* 返回示例
+
+```json
+[
+ {
+ "id":"java.lang.RuntimeExceptionRuntimeException认证失败",
+ "name":"RuntimeException",
+ "className":"java.lang.RuntimeException",
+ "message":"认证失败",
+ "value":82
+ },
+ {
+ "id":"java.lang.RuntimeExceptionRuntimeException获取信息失败",
+ "name":"RuntimeException",
+ "className":"java.lang.RuntimeException",
+ "message":"获取信息失败",
+ "value":91
+ }
+]
+```
+
+## 获取异常详情
+
+* 接口名
+
+> `GET` /koTime/getMethodsByExceptionId?exceptionId=xx
+
+* 返回示例
+```json
+[
+ {
+ "id":"java.lang.RuntimeExceptionRuntimeException获取信息失败",
+ "name":"RuntimeException",
+ "className":"java.lang.RuntimeException",
+ "message":"获取信息失败",
+ "location":91,
+ "methodName":"getParents",
+ "occurClassName":"com.example.demo.service.impl.IndexServiceImpl"
+ }
+]
+```
+
+## 获取当前配置信息
+
+* 接口名
+
+>`GET` /koTime/getConfig
+
+* 返回示例
+
+```json
+{
+ "logLanguage":"chinese",
+ "kotimeEnable":true,
+ "logEnable":false,
+ "timeThreshold":"800.0",
+ "exceptionEnable":true,
+ "dataSaver":"memory"
+}
+```
+
+## 更新当前配置信息
+
+* 接口名
+
+>`POST` /koTime/updateConfig
+
+* 参数示例
+
+```json
+{
+ "kotimeEnable":true,
+ "logEnable":false,
+ "timeThreshold":"800.0",
+ "exceptionEnable":true
+}
+```
\ No newline at end of file
diff --git a/docs/apis.png b/docs/apis.png
new file mode 100644
index 0000000..4fb0cab
Binary files /dev/null and b/docs/apis.png differ
diff --git a/docs/ff.png b/docs/ff.png
new file mode 100644
index 0000000..8d55fc4
Binary files /dev/null and b/docs/ff.png differ
diff --git a/docs/getstart.md b/docs/getstart.md
index f661932..ec64487 100644
--- a/docs/getstart.md
+++ b/docs/getstart.md
@@ -7,7 +7,7 @@
cn.langpy
ko-time
- 1.9
+ 2.0.0
@@ -30,12 +30,12 @@
* 可选配置
>
-> koTime.enable=false # 是否开启koTime,默认开启,当为false时,关闭koTime
+> koTime.enable=true # 是否开启koTime,默认开启,当为false时,关闭koTime
> koTime.log.enable=false # 是否开启控制输出,默认false
> koTime.log.language=chinese # 控制台输出语言(english/chinese)默认chinese
> koTime.time.threshold=800.0 # 时间阈值,用于前端展示,大于阈值显示红色,小于阈值显示绿色,默认800
-> koTime.ui.template=thymeleaf # 前端页面模板,默认为freemarker,可选thymeleaf 与引入的pom依赖对应
-> koTime.exception.enable=true # 是否开启异常检测,默认为false,开启后会对方法内部抛出的异常进行统计 v1.9开始支持
+> koTime.ui.template=freemarker # 前端页面模板,默认为freemarker,可选thymeleaf 与引入的pom依赖对应
+> koTime.exception.enable=true # 是否开启异常检测,默认为false,开启后会对方法内部抛出的异常进行统计 v2.0.0开始支持
## 访问
diff --git a/docs/introduce.md b/docs/introduce.md
index d46272e..b09f49b 100644
--- a/docs/introduce.md
+++ b/docs/introduce.md
@@ -37,7 +37,9 @@ http://huoyo.gitee.io/ko-time/example
> V1.8:支持Mybatis的Mapper监测、新增最大/最小运行时间、修复小数位数过长页面边界溢出的bug
-> V1.9:添加异常监测,开放数据接口,修复与swagger冲突bug,添加配置动态更新功能以及重构数据存储机制
+> V1.9:过度版本
+
+> V2.0.0:添加异常监测,开放数据接口,修复与swagger冲突bug,添加配置动态更新功能以及重构数据存储机制
## 作者
> Huoyo/Zhang Chang
diff --git a/docs/pz.png b/docs/pz.png
new file mode 100644
index 0000000..993cc13
Binary files /dev/null and b/docs/pz.png differ
diff --git a/docs/uiguide.md b/docs/uiguide.md
new file mode 100644
index 0000000..65f3158
--- /dev/null
+++ b/docs/uiguide.md
@@ -0,0 +1,46 @@
+
+
+## 首页面板
+
+首页有六个统计指标,分别是
+
+`总接口数`、`延迟响应接口数`、`正常响应接口数`、`平均响应`、`最大响应`、`最小响应`
+
+
+接口是否延迟取决于`koTime.time.threshold`的配置,大于该阈值即表示延迟,显示为红色,如下图
+
+
+
+
+## 接口列表
+
+该列表展示的是监测到被请求过的接口,按照其平均响应时间倒序排列,超过`koTime.time.threshold`的接口显示红色,如下图:
+
+
+
+
+
+点击每一个接口后会显示该接口的方法调用链路、各个方法的运行时间以及该方法是否发生了异常,方法节点可拖动
+
+
+
+## 异常列表
+
+异常列表以异常为切入点,并显示每个异常发生的位置
+
+
+
+
+## 配置面板
+
+配置面板有四项配置,可在不重启系统的情况下进行配置
+
+`开启koTime监测` :该开关对应`koTime.enable`,默认开启,当不需要koTime时可选择关闭
+
+`开启异常监测` :该开关对应`koTime.exception.enable`,默认关闭,当需要时可选择开启
+
+`开启控制台日志` :该开关对应`koTime.log.enable`,默认关闭,当需要时可选择开启,即可在控制台打印日志
+
+`方法运行时间阈值` :该开关对应`koTime.time.threshold`,默认800ms,可调整,调整后接口列表和方法节点的颜色将以新的阈值变化
+
+
\ No newline at end of file
diff --git a/docs/webshow.md b/docs/webshow.md
deleted file mode 100644
index 3ac17a2..0000000
--- a/docs/webshow.md
+++ /dev/null
@@ -1,5 +0,0 @@
-
-## 首页
-
-访问/koTime路径后即可打开首页,如下图
-
diff --git a/docs/yc.png b/docs/yc.png
new file mode 100644
index 0000000..2c66f33
Binary files /dev/null and b/docs/yc.png differ
diff --git a/docs/zl.png b/docs/zl.png
new file mode 100644
index 0000000..2903b7c
Binary files /dev/null and b/docs/zl.png differ
diff --git a/pom.xml b/pom.xml
index de79199..3146cde 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
cn.langpy
ko-time
- 1.9-SNAPSHOT
+ 2.0.0
koTime
koTime
diff --git a/src/main/java/cn/langpy/kotime/data/MemoryBase.java b/src/main/java/cn/langpy/kotime/data/MemoryBase.java
index 3de0777..78862d9 100644
--- a/src/main/java/cn/langpy/kotime/data/MemoryBase.java
+++ b/src/main/java/cn/langpy/kotime/data/MemoryBase.java
@@ -7,10 +7,7 @@ import cn.langpy.kotime.util.Context;
import cn.langpy.kotime.util.MethodType;
import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
@@ -70,7 +67,7 @@ public class MemoryBase implements GraphService {
exceptionRelation.setId(sourceMethodNode.getId() + exceptionNode.getId());
exceptionRelation.setSourceId(sourceMethodNode.getId());
exceptionRelation.setTargetId(exceptionNode.getId());
- exceptionRelation.setLocation(exceptionNode.getLocation());
+ exceptionRelation.setLocation(exceptionNode.getValue());
ExceptionRelation old = exceptionRelations.get(exceptionRelation.getId());
if (null == old) {
exceptionRelations.put(exceptionRelation.getId(), exceptionRelation);
@@ -118,7 +115,13 @@ public class MemoryBase implements GraphService {
for (MethodNode methodNode : methodNodes.values()) {
if (MethodType.Controller == methodNode.getMethodType()) {
String id = methodNode.getId();
- MethodRelation relation = methodRelations.values().stream().filter(methodRelation -> methodRelation.getTargetId().equals(id)).findFirst().get();
+ Optional relations = methodRelations.values().stream().filter(methodRelation -> methodRelation.getTargetId().equals(id)).findFirst();
+ MethodRelation relation = null;
+ if (relations.isPresent()) {
+ relation = relations.get();
+ }else{
+ continue;
+ }
MethodInfo methodInfo = new MethodInfo();
methodInfo.setId(methodNode.getId());
methodInfo.setName(methodNode.getName());
diff --git a/src/main/java/cn/langpy/kotime/handler/RunTimeHandler.java b/src/main/java/cn/langpy/kotime/handler/RunTimeHandler.java
index 17ef383..2ce8127 100644
--- a/src/main/java/cn/langpy/kotime/handler/RunTimeHandler.java
+++ b/src/main/java/cn/langpy/kotime/handler/RunTimeHandler.java
@@ -27,7 +27,7 @@ public class RunTimeHandler implements MethodInterceptor {
exception.setName(e.getClass().getSimpleName());
exception.setClassName(e.getClass().getName());
exception.setMessage(e.getMessage());
- exception.setLocation(e.getStackTrace()[0].getLineNumber());
+ exception.setValue(e.getStackTrace()[0].getLineNumber());
exception.setId(exception.getClassName() + exception.getName() + exception.getMessage());
MethodNode current = InvokeService.getCurrentMethodNode(invocation, 0.0);
if (current.getClassName().equals(e.getStackTrace()[0].getClassName())) {
diff --git a/src/main/java/cn/langpy/kotime/model/ExceptionNode.java b/src/main/java/cn/langpy/kotime/model/ExceptionNode.java
index 72661e9..d90668b 100644
--- a/src/main/java/cn/langpy/kotime/model/ExceptionNode.java
+++ b/src/main/java/cn/langpy/kotime/model/ExceptionNode.java
@@ -7,7 +7,7 @@ public class ExceptionNode {
private String name;
private String className;
private String message;
- private Integer location;
+ private Integer value;
public String getId() {
return id;
@@ -41,12 +41,12 @@ public class ExceptionNode {
this.message = message;
}
- public Integer getLocation() {
- return location;
+ public Integer getValue() {
+ return value;
}
- public void setLocation(Integer location) {
- this.location = location;
+ public void setValue(Integer value) {
+ this.value = value;
}
@Override
diff --git a/src/main/java/cn/langpy/kotime/model/MethodInfo.java b/src/main/java/cn/langpy/kotime/model/MethodInfo.java
index 631a55c..09221e7 100644
--- a/src/main/java/cn/langpy/kotime/model/MethodInfo.java
+++ b/src/main/java/cn/langpy/kotime/model/MethodInfo.java
@@ -7,7 +7,7 @@ import java.util.List;
import java.util.Objects;
-public class MethodInfo implements Comparable {
+public class MethodInfo implements Comparable {
private String id;
private String name;
private String className;
diff --git a/src/main/resources/static/graph.js b/src/main/resources/static/graph.js
index 9d43d15..a8de2cf 100644
--- a/src/main/resources/static/graph.js
+++ b/src/main/resources/static/graph.js
@@ -22,13 +22,13 @@ function MethodGraph(canvas) {
}
let $info = "\n" +
"";
$('#layerDemo').append($info)
$("#" + name).css({
@@ -147,14 +147,14 @@ function MethodGraph(canvas) {
let pmoveNode = document.getElementById(nodeKey)
let nl = nx - o.moveNodeX ;
let nt = ny - o.moveNodeY ;
- if (nl>6) {
+ if (nl>10) {
pmoveNode.style.left = Number(pmoveNode.style.left.replace('px',''))+10 + 'px';
- }else if(nl<-6){
+ }else if(nl<-10){
pmoveNode.style.left = Number(pmoveNode.style.left.replace('px',''))-10 + 'px';
}
- if (nt>4) {
+ if (nt>6) {
pmoveNode.style.top = Number(pmoveNode.style.top.replace('px',''))+10 + 'px';
- }else if (nt<-4){
+ }else if (nt<-6){
pmoveNode.style.top = Number(pmoveNode.style.top.replace('px',''))-10 + 'px';
}
let childrenId = o.allNodeEnds.get(nodeKey)
diff --git a/src/main/resources/templates/index-thymeleaf.html b/src/main/resources/templates/index-thymeleaf.html
index b0ddf1e..8e321c2 100644
--- a/src/main/resources/templates/index-thymeleaf.html
+++ b/src/main/resources/templates/index-thymeleaf.html
@@ -79,8 +79,8 @@
-
-
+
+