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`的配置,大于该阈值即表示延迟,显示为红色,如下图 + +![](zl.png) + + +## 接口列表 + +该列表展示的是监测到被请求过的接口,按照其平均响应时间倒序排列,超过`koTime.time.threshold`的接口显示红色,如下图: +![](apis.png) + + + + +点击每一个接口后会显示该接口的方法调用链路、各个方法的运行时间以及该方法是否发生了异常,方法节点可拖动 +![](ff.png) + + +## 异常列表 + +异常列表以异常为切入点,并显示每个异常发生的位置 + +![](yc.png) + + +## 配置面板 + +配置面板有四项配置,可在不重启系统的情况下进行配置 + +`开启koTime监测` :该开关对应`koTime.enable`,默认开启,当不需要koTime时可选择关闭 + +`开启异常监测` :该开关对应`koTime.exception.enable`,默认关闭,当需要时可选择开启 + +`开启控制台日志` :该开关对应`koTime.log.enable`,默认关闭,当需要时可选择开启,即可在控制台打印日志 + +`方法运行时间阈值` :该开关对应`koTime.time.threshold`,默认800ms,可调整,调整后接口列表和方法节点的颜色将以新的阈值变化 + +![](pz.png) \ 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 @@

- - + +