update docs
@ -1,6 +1,6 @@
|
|||||||

|

|
||||||
|
|
||||||
<small>v2.0.9@Huoyo</small>
|
<small>v2.2.0@Huoyo</small>
|
||||||
|
|
||||||
> koTime是一个springboot方法调用链路追踪和运行时长统计工具
|
> koTime是一个springboot方法调用链路追踪和运行时长统计工具
|
||||||
|
|
||||||
@ -9,4 +9,4 @@
|
|||||||
|
|
||||||
|
|
||||||
[Gitee](https://gitee.com/huoyo/ko-time)
|
[Gitee](https://gitee.com/huoyo/ko-time)
|
||||||
[文档教程](v204/introduce)
|
[文档教程](v220/introduce)
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
* 其他版本教程
|
* 其他版本教程
|
||||||
|
* [V2.2.0+](v220/getstart)
|
||||||
* [V2.0.4+](v204/getstart)
|
* [V2.0.4+](v204/getstart)
|
||||||
* [V2.0.3](v203/getstart)
|
* [V2.0.3](v203/getstart)
|
||||||
* [V2.0.2](v202/getstart)
|
* [V2.0.2](v202/getstart)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta name="keywords" content="链路追踪,方法调用链路,springboot,kotime教程,调用可视化,耗时统计,kotime文档,kotime手册">
|
<meta name="keywords" content="kotime教程,kotime文档,链路追踪,方法调用链路,springboot,调用可视化,耗时统计,kotime手册">
|
||||||
<meta name="description" content="koTime是一个springboot项目性能分析工具,通过追踪方法调用链路以及对应的运行时长快速定位性能瓶颈">
|
<meta name="description" content="koTime是一个springboot项目性能分析工具,通过追踪方法调用链路以及对应的运行时长快速定位性能瓶颈">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
|||||||
6
docs/v220/_sidebar.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
* [简介](v220/introduce)
|
||||||
|
* [快速上手](v220/getstart)
|
||||||
|
* [高级特性](v220/more)
|
||||||
|
* [UI页面说明](v220/uiguide)
|
||||||
|
* [API数据接口](v220/apiintro)
|
||||||
|
* [常见问题](v220/questions)
|
||||||
282
docs/v220/apiintro.md
Normal file
@ -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",
|
||||||
|
"enable":true,
|
||||||
|
"logEnable":false,
|
||||||
|
"threshold":"800.0",
|
||||||
|
"exceptionEnable":true,
|
||||||
|
"dataSaver":"memory"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 更新当前配置信息
|
||||||
|
|
||||||
|
* 接口名
|
||||||
|
|
||||||
|
>`POST` /koTime/updateConfig
|
||||||
|
|
||||||
|
* 参数示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"enable":true,
|
||||||
|
"logEnable":false,
|
||||||
|
"threshold":"800.0",
|
||||||
|
"exceptionEnable":true
|
||||||
|
}
|
||||||
|
```
|
||||||
BIN
docs/v220/apis.png
Normal file
|
After Width: | Height: | Size: 187 KiB |
BIN
docs/v220/ff.png
Normal file
|
After Width: | Height: | Size: 267 KiB |
BIN
docs/v220/ffss.png
Normal file
|
After Width: | Height: | Size: 202 KiB |
71
docs/v220/getstart.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
## 引入依赖
|
||||||
|
|
||||||
|
在pom.xml文件中引入
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.langpy</groupId>
|
||||||
|
<artifactId>ko-time</artifactId>
|
||||||
|
<version>2.2.0.BETA</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置
|
||||||
|
|
||||||
|
在`application.properties`文件中进行配置
|
||||||
|
|
||||||
|
* 必填配置
|
||||||
|
|
||||||
|
>
|
||||||
|
> ko-time.pointcut=`execution(public * com.huoyo..*.*(..))` # 需要监测的切面范围,参考aop的@pointcut 或者左侧常见问题
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
* 可选配置(以下配置一般不用设置)
|
||||||
|
|
||||||
|
>
|
||||||
|
> ko-time.enable=true # 是否开启koTime,默认开启,当为false时,关闭koTime
|
||||||
|
> ko-time.log-enable=false # 是否开启控制输出,默认false
|
||||||
|
> ko-time.log-language=chinese # 控制台输出语言(english/chinese)默认chinese
|
||||||
|
> ko-time.threshold=800.0 # 时间阈值,用于前端展示,大于阈值显示红色,小于阈值显示绿色,默认800
|
||||||
|
> ko-time.context-path=http://localhost:80 # 前端页面调用接口的上下文环境,无法自动获取时可手动配置,一般情况切记不要配置 v2.0.1开始支持
|
||||||
|
> ko-time.exception-enable=true # 是否开启异常检测,默认为false,开启后会对方法内部抛出的异常进行统计 v2.0.0开始支持
|
||||||
|
> ko-time.auth-enable=true # 是否开启认证,默认为false,开启后需要登录才能访问调用链路 v2.0.2开始支持
|
||||||
|
> ko-time.user-name=xxxx # 登录用户 v2.0.2开始支持
|
||||||
|
> ko-time.password=xxxx # 登录密码 v2.0.2开始支持
|
||||||
|
> ko-time.param-analyse=true #是否开启入参组合分析 默认开启 v2.0.8开始支持 双击方法节点即可看到效果
|
||||||
|
> ko-time.saver=memory #接口信息存储位置,可选{memory,database} 默认memory v2.2.0.BETA开始支持
|
||||||
|
> ko-time.thread-num=5 #调用信息存储线程数(为了不影响项目本身的性能,链路存储异步进行),默认5 v2.2.0.BETA开始支持
|
||||||
|
|
||||||
|
## 访问
|
||||||
|
|
||||||
|
> 注意:
|
||||||
|
> 1.引入了上面的依赖和配置以后,确认项目中是否有aop相关的包,koTime使用了@Aspect注解,未引入的自行引入,如aspectj或者spring-boot-starter-aop
|
||||||
|
> 2.做完前面的步骤,koTime的集成已经完毕,无需进行其他配置
|
||||||
|
> 3.如果后台有权限认证,需要放开`/koTime`和`/koTime/**`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* 启动项目访问 `/koTime` 路径即可
|
||||||
|
|
||||||
|
* 如果仅仅只是想统计某个方法,在方法上加上`@ComputeTime`即可,控制台会输出耗时
|
||||||
|
|
||||||
|
|
||||||
|
> 建议使用谷歌浏览器或者Edge浏览器,IE是不可能支持的
|
||||||
|
|
||||||
|
如果项目自定义的contextpath,访问如`http://localhost:8080/xxx服务/koTime`
|
||||||
|
|
||||||
|
如:application.properties中定义了 `server.servlet.context-path=/myservice`,那么访问路径为`http://localhost:8080/myservice/koTime`
|
||||||
|
|
||||||
|
如果页面能正常显示,但是无法获取方法链路,可配置`ko-time.context-path=http://localhost:8080/myservice`
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
**为了让作者不要偷懒,督促他好好维护和开发,我准备用金钱对他进行鞭笞**
|
||||||
|
|
||||||
|
<img src="v202/pay.jpg" width="15%" height="15%">
|
||||||
|
|
||||||
|
|
||||||
60
docs/v220/introduce.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
## 简介
|
||||||
|
koTime是一个springboot项目性能分析工具,通过追踪方法调用链路以及对应的运行时长快速定位性能瓶颈
|
||||||
|
|
||||||
|
## 预览
|
||||||
|
|
||||||
|
http://huoyo.gitee.io/ko-time/example
|
||||||
|
|
||||||
|
|
||||||
|
## 优点
|
||||||
|
|
||||||
|
> * 实时监听方法,统计运行时长
|
||||||
|
> * web展示方法调用链路,瓶颈可视化追踪
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 重要版本说明
|
||||||
|
|
||||||
|
> V1.0:基本功能
|
||||||
|
|
||||||
|
> V1.1:接口统计
|
||||||
|
|
||||||
|
> V1.2:不可用,错误版本
|
||||||
|
|
||||||
|
> V1.3:添加日志、时间阈值可配置
|
||||||
|
|
||||||
|
> V1.4:添加koTime.pointcut配置
|
||||||
|
|
||||||
|
> V1.8:支持Mybatis的Mapper监测、新增最大/最小运行时间、修复小数位数过长页面边界溢出的bug
|
||||||
|
|
||||||
|
> V2.0.0:添加异常监测,开放数据接口,修复与swagger冲突bug,添加配置动态更新功能以及重构数据存储机制
|
||||||
|
|
||||||
|
> V2.0.1:移除freemarker与thymeleaf;
|
||||||
|
移除spring.profiles.active=koTime配置;
|
||||||
|
优化方法链路获取机制(移除getAllStackTraces());
|
||||||
|
替换layui;
|
||||||
|
优化配置方式;
|
||||||
|
优化页面显示
|
||||||
|
|
||||||
|
> V2.0.2:新增登录认证;
|
||||||
|
优化页面加载;
|
||||||
|
修复方法循环调用栈溢出的bug
|
||||||
|
|
||||||
|
> V2.0.7:Controller层显示路由
|
||||||
|
|
||||||
|
> V2.0.8:入参组合分析
|
||||||
|
|
||||||
|
> V2.2.0:添加数据库存储支持
|
||||||
|
|
||||||
|
## 作者
|
||||||
|
|
||||||
|
> Huoyo/Zhang Chang
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**为了让作者不要偷懒,督促他好好维护和开发,我准备用金钱对他进行鞭笞**
|
||||||
|
|
||||||
|
<img src="v201/pay.jpg" width="15%" height="15%">
|
||||||
|
|
||||||
BIN
docs/v220/kotime.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
112
docs/v220/more.md
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
## 存储多样性
|
||||||
|
|
||||||
|
v2.2.0开始支持数据库存储接口信息功能,可在内存和数据库中进行切换
|
||||||
|
|
||||||
|
### 内存存储
|
||||||
|
|
||||||
|
更改配置:
|
||||||
|
|
||||||
|
> ko-time.saver=memory #默认存储方式,无需此配置也行
|
||||||
|
|
||||||
|
### 数据库存储
|
||||||
|
|
||||||
|
1.更改配置:
|
||||||
|
|
||||||
|
> ko-time.saver=database
|
||||||
|
|
||||||
|
2.数据表创建
|
||||||
|
|
||||||
|
```sql
|
||||||
|
create table ko_method_node (
|
||||||
|
id varchar(200) not null primary key comment '主键' ,
|
||||||
|
name varchar(200) null comment '类名+方法名' ,
|
||||||
|
class_name varchar(200) null comment '类名' ,
|
||||||
|
method_name varchar(200) null comment '方法名' ,
|
||||||
|
route_name varchar(200) null comment '路由,controller才有' ,
|
||||||
|
method_type varchar(64) null comment '方法类型'
|
||||||
|
) comment '方法信息表';
|
||||||
|
|
||||||
|
|
||||||
|
create table ko_method_relation (
|
||||||
|
id varchar(200) not null primary key comment '' ,
|
||||||
|
source_id varchar(200) null comment '调用方id' ,
|
||||||
|
target_id varchar(200) null comment '被调用方id' ,
|
||||||
|
avg_run_time numeric(10,2) null comment '平均耗时' ,
|
||||||
|
max_run_time numeric(10,2) null comment '最大耗时' ,
|
||||||
|
min_run_time numeric(10,2) null comment '最小耗时'
|
||||||
|
) comment '方法调用关系表';
|
||||||
|
|
||||||
|
;
|
||||||
|
create table ko_exception_node (
|
||||||
|
id varchar(200) not null primary key comment '主键' ,
|
||||||
|
name varchar(200) null comment '异常名' ,
|
||||||
|
class_name varchar(200) null comment '类名' ,
|
||||||
|
message varchar(200) null comment '异常消息'
|
||||||
|
) comment '异常表';
|
||||||
|
|
||||||
|
|
||||||
|
create table ko_exception_relation (
|
||||||
|
id varchar(200) not null primary key comment '' ,
|
||||||
|
source_id varchar(200 null comment '调用方法id' ,
|
||||||
|
target_id varchar(200) null comment '异常id' ,
|
||||||
|
location int null comment '异常位置'
|
||||||
|
) comment '异常关系表';
|
||||||
|
|
||||||
|
create table ko_param_ana (
|
||||||
|
source_id varchar(200) null comment '调用方法id' ,
|
||||||
|
params varchar(200) null comment '参数组合,-分隔' ,
|
||||||
|
avg_run_time numeric(10,2) null comment '平均耗时' ,
|
||||||
|
max_run_time numeric(10,2) null comment '最大耗时' ,
|
||||||
|
min_run_time numeric(10,2) null comment '最小耗时'
|
||||||
|
) comment '参数分析表';
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 方法调用信息扩展监听
|
||||||
|
|
||||||
|
如果需要做方法调用信息进行监听,然后做一些扩展的,可以使用此方法
|
||||||
|
|
||||||
|
1.新建监听类,实现InvokedHandler,并能加上注解@KoListener即可
|
||||||
|
|
||||||
|
```java
|
||||||
|
|
||||||
|
@KoListener
|
||||||
|
public class TestInvoke implements InvokedHandler {
|
||||||
|
@Override
|
||||||
|
public void onInvoked(MethodNode current, MethodNode parent, Parameter[] names, Object[] values) {
|
||||||
|
System.out.println("调用的方法:"+current);
|
||||||
|
System.out.println("调用当前方法的上一级方法:"+parent);
|
||||||
|
System.out.println("调用的方法-参数名称:"+names);
|
||||||
|
System.out.println("调用的方法-具体参数:"+values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2.如果需要监听异常情况
|
||||||
|
|
||||||
|
实现InvokedHandler的默认方法即可
|
||||||
|
|
||||||
|
```java
|
||||||
|
|
||||||
|
@KoListener
|
||||||
|
public class TestInvoke implements InvokedHandler {
|
||||||
|
@Override
|
||||||
|
public void onInvoked(MethodNode current, MethodNode parent, Parameter[] names, Object[] values) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onException(MethodNode current, MethodNode parent, ExceptionNode exception, Parameter[] names, Object[] values) {
|
||||||
|
System.out.println("异常:"+exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
**为了让作者不要偷懒,督促他好好维护和开发,我准备用金钱对他进行鞭笞**
|
||||||
|
|
||||||
|
<img src="v202/pay.jpg" width="15%" height="15%">
|
||||||
|
|
||||||
|
|
||||||
BIN
docs/v220/param.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
docs/v220/param2.png
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
docs/v220/pay.jpg
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
docs/v220/pz.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
94
docs/v220/questions.md
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
## 额外依赖引入
|
||||||
|
|
||||||
|
koTime使用了@Aspect注解,未引入 aop相关包的自行引入,如aspectj或者spring-boot-starter-aop
|
||||||
|
|
||||||
|
|
||||||
|
## pointcut写法参考
|
||||||
|
|
||||||
|
pointcut直接引用了aop中的写法,下面简要提供几个写法:
|
||||||
|
|
||||||
|
假设项目的包路径为:
|
||||||
|
|
||||||
|
```
|
||||||
|
com.huoyo.demo
|
||||||
|
|-controller
|
||||||
|
|-service
|
||||||
|
|-mapper
|
||||||
|
|-others
|
||||||
|
|-other1
|
||||||
|
|-other2
|
||||||
|
|-Test.java
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
想要切`cn.langpy.demo`下面的所有方法(包括子包中的),可以写:
|
||||||
|
|
||||||
|
> `execution(public * com.huoyo.demo..*.*(..))` #切记,是两个点.
|
||||||
|
|
||||||
|
|
||||||
|
只想要切`cn.langpy.demo.controller`下面的类的所有方法(不包括子包的),可以写:
|
||||||
|
|
||||||
|
> `execution(public * com.huoyo.demo.controller.*.*(..))` #切记,是一个点.
|
||||||
|
|
||||||
|
只想要切`cn.langpy.demo.others`下面的类的所有方法(不包括other1和other2下面的),可以写:
|
||||||
|
|
||||||
|
> `execution(public * com.huoyo.demo.others.*.*(..))`
|
||||||
|
|
||||||
|
只想要切`cn.langpy.demo.others`下面的类的所有方法(包括other1和other2),可以写:
|
||||||
|
|
||||||
|
> `execution(public * com.huoyo.demo.others..*.*(..))`
|
||||||
|
|
||||||
|
更多写法请详细参考aop
|
||||||
|
|
||||||
|
## 是否支持前后端分离项目
|
||||||
|
|
||||||
|
支持!
|
||||||
|
|
||||||
|
## 如何与shiro集成
|
||||||
|
|
||||||
|
koTime没有做相关方面的限制,在shiro的配置中将相关路径放开即可,如:
|
||||||
|
|
||||||
|
```Java
|
||||||
|
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
|
||||||
|
/*设置过滤*/
|
||||||
|
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
|
||||||
|
/*authc:所有url都必须认证通过才可以访问;*/
|
||||||
|
/*anon:所有url都都可以匿名访问*/
|
||||||
|
filterChainDefinitionMap.put("/koTime", "anon");
|
||||||
|
filterChainDefinitionMap.put("/koTime/**", "anon");
|
||||||
|
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 运行时间计算
|
||||||
|
|
||||||
|
运行时间分了三个指标:**平均运行时间、最大运行时间、最小运行时间**
|
||||||
|
|
||||||
|
平均运行时间会将方法下每一次的运行时间与之前的求平均
|
||||||
|
|
||||||
|
|
||||||
|
## 数据是否会保存
|
||||||
|
|
||||||
|
目前暂不支持数据的存储,也就是每一次项目重启之后,以往的统计数据都归0
|
||||||
|
|
||||||
|
## 集成是否需要复制资源文件
|
||||||
|
|
||||||
|
不需要复制 static和template 等资源文件,引入依赖时已自动集成
|
||||||
|
|
||||||
|
## 能正常启动但是页面样式不对
|
||||||
|
|
||||||
|
打开f12查看静态资源路径加载是否正确,如果不正确,手动配置属性`ko-time.context-path=http://ip:port/contextPath`
|
||||||
|
|
||||||
|
## V2.0.1开始更改了配置,V2.0.0的配置方式是否可用
|
||||||
|
|
||||||
|
V2.0.1开始,两种配置均生效,建议使用新的配置方式
|
||||||
|
|
||||||
|
## 问题咨询
|
||||||
|
|
||||||
|
访问[koTime开源地址](https://gitee.com/huoyo/ko-time)进行咨询
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**我觉得作者列的问题太少了,不能满足我,我准备用金钱对他进行鞭笞,并备注上本大爷的要求**
|
||||||
|
|
||||||
|
<img src="v201/pay.jpg" width="15%" height="15%">
|
||||||
BIN
docs/v220/test3.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
57
docs/v220/uiguide.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## 首页面板
|
||||||
|
|
||||||
|
首页有六个统计指标,分别是
|
||||||
|
|
||||||
|
`总接口数`、`延迟响应接口数`、`正常响应接口数`、`平均响应`、`最大响应`、`最小响应`
|
||||||
|
|
||||||
|
|
||||||
|
接口是否延迟取决于`ko-time.threshold`的配置,大于该阈值即表示延迟,显示为红色,如下图
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## 接口列表
|
||||||
|
|
||||||
|
该列表展示的是监测到被请求过的接口,按照其平均响应时间倒序排列,超过`ko-time.threshold`的接口显示红色,如下图:
|
||||||
|
|
||||||
|
可根据类名或者方法名模糊搜索,回车即可
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
点击每一个接口后会显示该接口的方法调用链路、各个方法的运行时间以及该方法是否发生了异常,方法节点可拖动
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
双击节点,可以查看不同入参组合下的调用时间分析(再双击即可收起):
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**-** 表示无参数
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 异常列表
|
||||||
|
|
||||||
|
异常列表以异常为切入点,并显示每个异常发生的位置
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## 配置面板
|
||||||
|
|
||||||
|
配置面板有四项配置,可在不重启系统的情况下进行配置
|
||||||
|
|
||||||
|
`开启koTime监测` :该开关对应`ko-time.enable`,默认开启,当不需要koTime时可选择关闭
|
||||||
|
|
||||||
|
`开启异常监测` :该开关对应`ko-time.exception-enable`,默认关闭,当需要时可选择开启
|
||||||
|
|
||||||
|
`开启控制台日志` :该开关对应`ko-time.log-enable`,默认关闭,当需要时可选择开启,即可在控制台打印日志
|
||||||
|
|
||||||
|
`方法运行时间阈值` :该开关对应`ko-time.threshold`,默认800ms,可调整,调整后接口列表和方法节点的颜色将以新的阈值变化
|
||||||
|
|
||||||
|

|
||||||
BIN
docs/v220/yc.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
docs/v220/zl.png
Normal file
|
After Width: | Height: | Size: 100 KiB |