添加配置项

This commit is contained in:
huoyo 2020-12-11 19:09:12 +08:00
parent 2360dfcd55
commit b159bf2288
14 changed files with 461 additions and 254 deletions

View File

@ -6,7 +6,7 @@
<groupId>cn.langpy</groupId>
<artifactId>ko-time</artifactId>
<version>1.0</version>
<version>1.1</version>
<name>koTime</name>
<description>koTime</description>
<licenses>

View File

@ -0,0 +1,52 @@
package cn.langpy.kotime.config;
import cn.langpy.kotime.model.KoTimeConfig;
import cn.langpy.kotime.util.Context;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
public class DefaultConfig {
@Value("${koTime.log.language:chinese}")
private String logLanguage;
@Value("${koTime.log.enable:false}")
private Boolean logEnable;
@Value("${koTime.time.threshold:800.0}")
private Double timeThreshold;
@PostConstruct
public void function() {
KoTimeConfig config = new KoTimeConfig();
config.setLogEnable(logEnable);
config.setLogLanguage(logLanguage);
config.setTimeThreshold(timeThreshold);
Context.setConfig(config);
}
public Double getTimeThreshold() {
return timeThreshold;
}
public void setTimeThreshold(Double timeThreshold) {
this.timeThreshold = timeThreshold;
}
public String getLogLanguage() {
return logLanguage;
}
public void setLogLanguage(String logLanguage) {
this.logLanguage = logLanguage;
}
public Boolean getLogEnable() {
return logEnable;
}
public void setLogEnable(Boolean logEnable) {
this.logEnable = logEnable;
}
}

View File

@ -2,8 +2,8 @@ package cn.langpy.kotime.controller;
import cn.langpy.kotime.model.RunTimeNode;
import cn.langpy.kotime.model.SystemStatistic;
import cn.langpy.kotime.service.RunTimeNodeService;
import cn.langpy.kotime.util.Context;
import cn.langpy.kotime.util.MethodType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@ -20,16 +20,17 @@ import java.util.List;
public class KoTimeController {
@GetMapping
public String index(Model model, HttpServletRequest request) {
List<RunTimeNode> list = Context.get(MethodType.Controller);
List<RunTimeNode> list = RunTimeNodeService.getControllers();
model.addAttribute("list",list);
SystemStatistic system = Context.getStatistic();
SystemStatistic system = RunTimeNodeService.getRunStatistic();
model.addAttribute("system",system);
model.addAttribute("config",Context.getConfig());
return "index";
}
@GetMapping("/getTree")
@ResponseBody
public RunTimeNode getTree(String methodName,Model model, HttpServletRequest request) {
return Context.getTree(methodName);
return RunTimeNodeService.getGraph(methodName);
}
}

View File

@ -27,6 +27,7 @@ public class ComputeTimeHandler {
long begin = System.nanoTime();
Object obj=pjp.proceed();
long end =System.nanoTime();
StackTraceElement stacks[] = Thread.currentThread().getStackTrace();
if ("chinese".equals(computeTime.value())) {
log.info("调用方法={},耗时={}毫秒",pjp.getTarget().getClass().getName()+"."+pjp.getSignature().getName(),(end-begin)/1000000);
}else{

View File

@ -2,8 +2,7 @@ package cn.langpy.kotime.handler;
import cn.langpy.kotime.model.RunTimeNode;
import cn.langpy.kotime.util.Common;
import cn.langpy.kotime.util.Context;
import cn.langpy.kotime.service.InvokeService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@ -11,7 +10,6 @@ import org.aspectj.lang.annotation.Pointcut;
@Aspect
public interface ComputeTimeHandlerInterface {
@Pointcut("")
void prog();
@ -21,9 +19,9 @@ public interface ComputeTimeHandlerInterface {
Object obj=pjp.proceed();
long end =System.nanoTime();
String packName = this.getClass().getPackage().getName();
RunTimeNode parent = Common.getParentRunTimeNode(packName);
RunTimeNode current = Common.getCurrentRunTimeNode(pjp,((end-begin)/1000000.0));
Context.set(parent,current);
RunTimeNode parent = InvokeService.getParentRunTimeNode(packName);
RunTimeNode current = InvokeService.getCurrentRunTimeNode(pjp,((end-begin)/1000000.0));
InvokeService.createGraph(parent,current);
return obj;
}

View File

@ -0,0 +1,41 @@
package cn.langpy.kotime.model;
public class KoTimeConfig {
private String logLanguage;
private Boolean logEnable;
private Double timeThreshold;
public Double getTimeThreshold() {
return timeThreshold;
}
public void setTimeThreshold(Double timeThreshold) {
this.timeThreshold = timeThreshold;
}
public String getLogLanguage() {
return logLanguage;
}
public void setLogLanguage(String logLanguage) {
this.logLanguage = logLanguage;
}
public Boolean getLogEnable() {
return logEnable;
}
public void setLogEnable(Boolean logEnable) {
this.logEnable = logEnable;
}
@Override
public String toString() {
return "KoTimeConfig{" +
"logLanguage='" + logLanguage + '\'' +
"timeThreshold='" + timeThreshold + '\'' +
", logEnable=" + logEnable +
'}';
}
}

View File

@ -65,4 +65,17 @@ public class SystemStatistic {
public void setNormalNum(Integer normalNum) {
this.normalNum = normalNum;
}
@Override
public String toString() {
return "SystemStatistic{" +
"name='" + name + '\'' +
", avgRunTime=" + avgRunTime +
", maxRunTime=" + maxRunTime +
", minRunTime=" + minRunTime +
", totalNum=" + totalNum +
", delayNum=" + delayNum +
", normalNum=" + normalNum +
'}';
}
}

View File

@ -0,0 +1,65 @@
package cn.langpy.kotime.service;
import cn.langpy.kotime.model.RunTimeNode;
import cn.langpy.kotime.util.Common;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class InvokeService {
public static RunTimeNode getParentRunTimeNode(String packName) {
String parentClassName = "";
String parentMothodName = "";
StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
StackTraceElement stack = Common.filter(stacks,packName);
if (stack!=null) {
parentClassName = stack.getClassName();
parentMothodName = stack.getMethodName();
}
RunTimeNode parent = new RunTimeNode();
parent.setClassName(parentClassName);
parent.setMethodName(parentMothodName);
parent.setName(parentClassName.substring(parentClassName.lastIndexOf(".")+1)+"."+parentMothodName);
parent.setMethodType(Common.getMethodType(parentClassName));
parent.setChildren(new ArrayList<>());
return parent;
}
public static RunTimeNode getCurrentRunTimeNode(ProceedingJoinPoint pjp, Double runTime) {
String className = pjp.getTarget().getClass().getName();
String methodName = pjp.getSignature().getName();
RunTimeNode current = new RunTimeNode();
current.setName(className.substring(className.lastIndexOf(".")+1)+"."+methodName);
current.setClassName(className);
current.setMethodName(methodName);
current.setAvgRunTime(runTime);
current.setChildren(new ArrayList<>());
current.setMethodType(Common.getMethodType(pjp));
return current;
}
public static void createGraph(RunTimeNode parent, RunTimeNode current) {
if (current.getMethodName().contains("$")) {
return;
}
Common.showLog(current);
String parentKey = parent.getClassName()+"."+parent.getMethodName();
String currentKey = current.getClassName()+"."+current.getMethodName();
if (".".equals(parentKey)) {
RunTimeNodeService.addOrUpdate(currentKey,current);
}else if (RunTimeNodeService.containsNode(parent)) {
RunTimeNodeService.addOrUpdateChildren(parent,current);
}else{
List<RunTimeNode> list = new ArrayList<>();
list.add(current);
parent.setChildren(list);
RunTimeNodeService.add(parentKey,parent);
}
}
}

View File

@ -0,0 +1,91 @@
package cn.langpy.kotime.service;
import cn.langpy.kotime.model.RunTimeNode;
import cn.langpy.kotime.model.SystemStatistic;
import cn.langpy.kotime.util.Context;
import cn.langpy.kotime.util.GraphMap;
import cn.langpy.kotime.util.MethodType;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class RunTimeNodeService {
public static void addOrUpdate(String key, RunTimeNode runTimeNode) {
if (GraphMap.containsKey(key)) {
GraphMap.get(key).setAvgRunTime(runTimeNode.getAvgRunTime());
}else{
GraphMap.put(key,runTimeNode);
}
}
public static void add(String key, RunTimeNode runTimeNode) {
GraphMap.put(key,runTimeNode);
}
public static boolean containsKey(String key) {
return GraphMap.containsKey(key);
}
public static boolean containsNode(RunTimeNode node) {
String key = node.getClassName()+"."+node.getMethodName();
return GraphMap.containsKey(key);
}
public static RunTimeNode getRunTimeNode(String key) {
return GraphMap.get(key);
}
public static void addOrUpdateChildren(RunTimeNode parent, RunTimeNode current) {
String parentKey = parent.getClassName()+"."+parent.getMethodName();
RunTimeNode hisRunTimeNode = RunTimeNodeService.getRunTimeNode(parentKey);
List<RunTimeNode> hisRunTimeNodeChildren = hisRunTimeNode.getChildren();
if (hisRunTimeNodeChildren!=null) {
if (hisRunTimeNodeChildren.contains(current)) {
updateChildren(current,hisRunTimeNodeChildren);
}else{
hisRunTimeNodeChildren.add(current);
}
} else {
List<RunTimeNode> list = new ArrayList<>();
list.add(current);
hisRunTimeNode.setChildren(list);
}
GraphMap.put(parentKey,hisRunTimeNode);
}
public static void updateChildren(RunTimeNode child, List<RunTimeNode> hisRunTimeNodeChildren) {
int hisLength = hisRunTimeNodeChildren.size();
for (int i = 0; i < hisLength; i++) {
if (hisRunTimeNodeChildren.get(i)==child) {
child.setAvgRunTime((child.getAvgRunTime()+hisRunTimeNodeChildren.get(i).getAvgRunTime())/2.0);
hisRunTimeNodeChildren.set(i,child) ;
break;
}
}
}
public static SystemStatistic getRunStatistic() {
List<RunTimeNode> controllerApis = GraphMap.get(MethodType.Controller);
SystemStatistic systemStatistic = new SystemStatistic();
int delayNum = (int)controllerApis.stream().filter(controllerApi -> controllerApi.getAvgRunTime() >= Context.getConfig().getTimeThreshold()).count();
systemStatistic.setDelayNum(delayNum);
int normalNum = (int)controllerApis.stream().filter(controllerApi -> controllerApi.getAvgRunTime() < Context.getConfig().getTimeThreshold()).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));
systemStatistic.setMaxRunTime(max);
systemStatistic.setMinRunTime(min);
systemStatistic.setAvgRunTime(avg);
return systemStatistic;
}
public static List<RunTimeNode> getControllers() {
List<RunTimeNode> list = GraphMap.get(MethodType.Controller);
return list;
}
public static RunTimeNode getGraph(String methodName) {
return GraphMap.getTree(methodName);
}
}

View File

@ -1,52 +1,30 @@
package cn.langpy.kotime.util;
import cn.langpy.kotime.model.RunTimeNode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
@Slf4j
public class Common {
public static RunTimeNode getParentRunTimeNode(String packName) {
String parentClassName = "";
String parentMothodName = "";
StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
public static StackTraceElement filter(StackTraceElement[] stacks,String packName) {
String[] packNameSplit = packName.split("\\.");
String filter = packNameSplit.length>1 ? packNameSplit[0]+"."+packNameSplit[1] : packNameSplit[0];
int stacksLength = stacks.length;
for (int i = 0; i < stacksLength; i++) {
StackTraceElement stack = stacks[i];
if (stack.getClassName().startsWith(filter)&& !stack.getClassName().contains("$")) {
parentClassName = stack.getClassName();
parentMothodName = stack.getMethodName();
break;
return stack;
}
}
RunTimeNode parent = new RunTimeNode();
parent.setClassName(parentClassName);
parent.setMethodName(parentMothodName);
parent.setName(parentClassName.substring(parentClassName.lastIndexOf(".")+1)+"."+parentMothodName);
parent.setMethodType(getMethodType(parentClassName));
parent.setChildren(new ArrayList<>());
return parent;
return null;
}
public static RunTimeNode getCurrentRunTimeNode(ProceedingJoinPoint pjp,Double runTime) {
String className = pjp.getTarget().getClass().getName();
String methodName = pjp.getSignature().getName();
RunTimeNode current = new RunTimeNode();
current.setName(className.substring(className.lastIndexOf(".")+1)+"."+methodName);
current.setClassName(className);
current.setMethodName(methodName);
current.setAvgRunTime(runTime);
current.setChildren(new ArrayList<>());
current.setMethodType(getMethodType(pjp));
return current;
}
public static MethodType getMethodType(ProceedingJoinPoint pjp) {
MethodType methodType = null;
@ -64,7 +42,7 @@ public class Common {
methodType = MethodType.Controller;
}else if (className.contains("service")) {
methodType = MethodType.Service;
}else if (className.contains("dao") || className.contains("mapper")) {
}else if (className.contains("dao") || className.contains("mapper")|| className.contains( "com.sun.proxy.$Proxy")) {
methodType = MethodType.Dao;
}else{
methodType = MethodType.Others;
@ -80,7 +58,7 @@ public class Common {
methodType = MethodType.Controller;
}else if (className.contains("service")) {
methodType = MethodType.Service;
}else if (className.contains("dao") || className.contains("mapper")) {
}else if (className.contains("dao") || className.contains("mapper")|| className.contains( "com.sun.proxy.$Proxy")) {
methodType = MethodType.Dao;
}else{
methodType = MethodType.Others;
@ -88,4 +66,14 @@ public class Common {
return methodType;
}
public static void showLog(RunTimeNode current) {
String currentKey = current.getClassName()+"."+current.getMethodName();
if (Context.getConfig().getLogEnable() && "chinese".equals(Context.getConfig().getLogLanguage())) {
log.info("调用方法="+currentKey+",耗时="+current.getAvgRunTime()+"毫秒");
}else if (Context.getConfig().getLogEnable() && "english".equals(Context.getConfig().getLogLanguage())) {
log.info("method="+currentKey+"runTime="+current.getAvgRunTime()+"ms");
}
}
}

View File

@ -1,112 +1,16 @@
package cn.langpy.kotime.util;
import cn.langpy.kotime.model.RunTimeNode;
import cn.langpy.kotime.model.SystemStatistic;
import cn.langpy.kotime.model.KoTimeConfig;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class Context {
private static KoTimeConfig config;
private static Map<String, RunTimeNode> runTimeNodeMap;
static {
runTimeNodeMap = new HashMap<>();
public static void setConfig(KoTimeConfig koTimeConfig) {
config = koTimeConfig;
}
public static void set(RunTimeNode parent,RunTimeNode current) {
String parentKey = parent.getClassName()+"."+parent.getMethodName();
String currentKey = current.getClassName()+"."+current.getMethodName();
if (!currentKey.contains("$")) {
log.info("调用方法="+currentKey+",耗时="+current.getAvgRunTime()+"毫秒");
}else {
return;
}
if (".".equals(parentKey)) {
if (runTimeNodeMap.containsKey(currentKey)) {
runTimeNodeMap.get(currentKey).setAvgRunTime(current.getAvgRunTime());
}else{
runTimeNodeMap.put(currentKey,current);
}
}else if (runTimeNodeMap.containsKey(parentKey)) {
RunTimeNode hisRunTimeNode = runTimeNodeMap.get(parentKey);
List<RunTimeNode> hisRunTimeNodeChildren = hisRunTimeNode.getChildren();
if (hisRunTimeNodeChildren!=null) {
if (hisRunTimeNodeChildren.contains(current)) {
int hisLength = hisRunTimeNodeChildren.size();
for (int i = 0; i < hisLength; i++) {
if (hisRunTimeNodeChildren.get(i)==current) {
current.setAvgRunTime((current.getAvgRunTime()+hisRunTimeNode.getChildren().get(i).getAvgRunTime())/2.0);
hisRunTimeNodeChildren.set(i,current) ;
break;
}
}
}else{
hisRunTimeNodeChildren.add(current);
}
} else {
List<RunTimeNode> list = new ArrayList<>();
list.add(current);
hisRunTimeNode.setChildren(list);
}
runTimeNodeMap.put(parentKey,hisRunTimeNode);
}else{
List<RunTimeNode> list = new ArrayList<>();
list.add(current);
parent.setChildren(list);
runTimeNodeMap.put(parentKey,parent);
public static KoTimeConfig getConfig() {
return config ;
}
}
public static RunTimeNode get(String key) {
return runTimeNodeMap.get(key);
}
public static List<RunTimeNode> get(MethodType methodType) {
return runTimeNodeMap.values().stream()
.filter(runTimeNode -> runTimeNode.getMethodType()==methodType)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
}
public static RunTimeNode getTree(String key) {
RunTimeNode root = runTimeNodeMap.get(key);
if (root==null) {
return root;
}
root.setValue(root.getAvgRunTime());
List<RunTimeNode> children = root.getChildren();
if (children!=null&&children.size()>0) {
children.forEach(child->{
String childKey = child.getClassName()+"."+child.getMethodName();
RunTimeNode newChild = getTree(childKey);
if (newChild!=null) {
child.setChildren(newChild.getChildren());
child.setValue(child.getAvgRunTime());
}
});
}
return root;
}
public static SystemStatistic getStatistic() {
List<RunTimeNode> controllerApis = get(MethodType.Controller);
SystemStatistic systemStatistic = new SystemStatistic();
int delayNum = (int)controllerApis.stream().filter(controllerApi -> controllerApi.getAvgRunTime() >= 800).count();
systemStatistic.setDelayNum(delayNum);
int normalNum = (int)controllerApis.stream().filter(controllerApi -> controllerApi.getAvgRunTime() < 800).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));
systemStatistic.setMaxRunTime(max);
systemStatistic.setMinRunTime(min);
systemStatistic.setAvgRunTime(avg);
return systemStatistic;
}
}

View File

@ -0,0 +1,57 @@
package cn.langpy.kotime.util;
import cn.langpy.kotime.model.RunTimeNode;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GraphMap {
/*只需保证可见性,无需保证线程安全*/
private volatile static Map<String, RunTimeNode> runTimeNodeMap;
static {
runTimeNodeMap = new HashMap<>();
}
public static RunTimeNode get(String key) {
return runTimeNodeMap.get(key);
}
public static RunTimeNode put(String key, RunTimeNode runTimeNode) {
return runTimeNodeMap.put(key,runTimeNode);
}
public static boolean containsKey(String key) {
return GraphMap.runTimeNodeMap.containsKey(key);
}
public static List<RunTimeNode> get(MethodType methodType) {
return runTimeNodeMap.values().stream()
.filter(runTimeNode -> runTimeNode.getMethodType()==methodType)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
}
public static RunTimeNode getTree(String key) {
RunTimeNode root = runTimeNodeMap.get(key);
if (root==null) {
return root;
}
root.setValue(root.getAvgRunTime());
List<RunTimeNode> children = root.getChildren();
if (children!=null&&children.size()>0) {
children.forEach(child->{
String childKey = child.getClassName()+"."+child.getMethodName();
RunTimeNode newChild = getTree(childKey);
if (newChild!=null) {
child.setChildren(newChild.getChildren());
child.setValue(child.getAvgRunTime());
}
});
}
return root;
}
}

View File

@ -0,0 +1,98 @@
function getOption(data){
return {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: [
{
type: 'tree',
// initialTreeDepth: 3,
data: [data],
top: '1%',
left: '15%',
bottom: '1%',
right: '10%',
roam: true,
symbolSize: 20,
itemStyle: {
borderColor: 'green'
},
label: {
position: 'right',
formatter: function(params){
var bg = "titleBgGreen"
if (params.value>800) {
bg = "titleBgRed"
}
return [
'{'+bg+'| 指标}',
' {aa|}方法:'+params.name+" ",
'{hr|}',
' {aa|}耗时: '+params.data.avgRunTime+" ms ",
'{hr|}',
' {aa|}类型: '+params.data.methodType+" "
].join('\n');
},
backgroundColor: '#ddd',
borderColor: '#88e781',
borderWidth: 1,
borderRadius: 5,
color: '#000',
fontSize: 12,
rich: {
titleBgGreen: {
align: 'left',
backgroundColor: '#59977e',
height: 20,
borderRadius: [5, 5, 0, 0],
padding: [0, 0, 0, 0],
width: '100%',
color: '#eee'
},
titleBgRed: {
align: 'left',
backgroundColor: '#dc1d16',
height: 20,
borderRadius: [5, 5, 0, 0],
padding: [0, 0, 0, 0],
width: '100%',
color: '#eee'
},
hr: {
borderColor: '#777',
width: '100%',
borderWidth: 0.5,
height: 0
},
aa: {
lineHeight: 20,
borderColor: '#111111',
height: 20,
borderRadius: [5, 5, 0, 0],
padding: [0, 0, 0, 0],
width: '0%'
},
t: {
align: 'center'
}
}
},
leaves: {
label: {
position: 'right',
verticalAlign: 'middle',
align: 'left'
}
},
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750
}
]
}
}

View File

@ -48,15 +48,15 @@
</fieldset>
<ul class="site-doc-icon site-doc-anim">
<li>
<div class="layui-anim" style=" <#if system.avgRunTime gt 800 >background-color: #da3f0b;</#if>" data-anim="layui-anim-up">${system.avgRunTime}</div>
<div class="layui-anim" style=" <#if system.avgRunTime gt config.timeThreshold >background-color: #da3f0b;</#if>" data-anim="layui-anim-up">${system.avgRunTime}</div>
<div class="code">平均响应ms</div>
</li>
<li>
<div class="layui-anim" style=" <#if system.maxRunTime gt 800 >background-color: #da3f0b;</#if>" data-anim="layui-anim-upbit">${system.maxRunTime}</div>
<div class="layui-anim" style=" <#if system.maxRunTime gt config.timeThreshold >background-color: #da3f0b;</#if>" data-anim="layui-anim-upbit">${system.maxRunTime}</div>
<div class="code">最大响应ms</div>
</li>
<li>
<div class="layui-anim" style=" <#if system.minRunTime gt 800 >background-color: #da3f0b;</#if>" data-anim="layui-anim-scale">${system.minRunTime}</div>
<div class="layui-anim" style=" <#if system.minRunTime gt config.timeThreshold >background-color: #da3f0b;</#if>" data-anim="layui-anim-scale">${system.minRunTime}</div>
<div class="code">最小响应ms</div>
</li>
</ul>
@ -68,7 +68,7 @@
<div class="layui-colla-item" >
<h2 class="layui-colla-title" id="${runtime.className}.${runtime.methodName}">
${runtime.className}#${runtime.methodName}&nbsp
<span class="layui-badge <#if runtime.avgRunTime gt 800 >layui-bg-red
<span class="layui-badge <#if runtime.avgRunTime gt config.timeThreshold >layui-bg-red
<#else>layui-bg-green
</#if>">平均响应 ${runtime.avgRunTime} 毫秒</span>
</h2>
@ -100,18 +100,11 @@
</div>
</div>
<!--<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">-->
<!-- <legend>接口方法列表</legend>-->
<!--</fieldset>-->
<script src="${ctx.contextPath}/static/layui/layui.js" charset="utf-8"></script>
<script src="${ctx.contextPath}/static/jquery.min.js"></script>
<script src="${ctx.contextPath}/static/echarts.min.js"></script>
<!--<script src="https://cdn.jsdelivr.net/npm/echarts@4/dist/echarts.min.js?_v_=1607268016278" rel="external nofollow" ></script>-->
<!-- 注意如果你直接复制所有代码到本地上述js路径需要改成你本地的 -->
<script src="${ctx.contextPath}/static/config.js"></script>
<script >
$(document).ready(function() {
@ -119,7 +112,6 @@
var element = layui.element;
var layer = layui.layer;
//监听折叠
element.on('collapse(test)', function (data) {
id = data.title['0'].id
show(data.content['0'],id)
@ -135,102 +127,7 @@
echarts.util.each(data.children, function (datum, index) {
index % 2 === 0 && (datum.collapsed = true);
});
myChart.setOption(option = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: [
{
type: 'tree',
// initialTreeDepth: 3,
data: [data],
top: '1%',
left: '15%',
bottom: '1%',
right: '10%',
roam: true,
symbolSize: 20,
itemStyle: {
borderColor: 'green'
},
label: {
position: 'right',
formatter: function(params){
var bg = "titleBgGreen"
if (params.value>800) {
bg = "titleBgRed"
}
return [
'{'+bg+'| 指标}',
' {aa|}方法:'+params.name+" ",
'{hr|}',
' {aa|}耗时: '+params.data.avgRunTime+" ms ",
'{hr|}',
' {aa|}类型: '+params.data.methodType+" "
].join('\n');
},
backgroundColor: '#ddd',
borderColor: '#88e781',
borderWidth: 1,
borderRadius: 5,
color: '#000',
fontSize: 12,
rich: {
titleBgGreen: {
align: 'left',
backgroundColor: '#59977e',
height: 20,
borderRadius: [5, 5, 0, 0],
padding: [0, 0, 0, 0],
width: '100%',
color: '#eee'
},
titleBgRed: {
align: 'left',
backgroundColor: '#dc1d16',
height: 20,
borderRadius: [5, 5, 0, 0],
padding: [0, 0, 0, 0],
width: '100%',
color: '#eee'
},
hr: {
borderColor: '#777',
width: '100%',
borderWidth: 0.5,
height: 0
},
aa: {
lineHeight: 20,
borderColor: '#111111',
height: 20,
borderRadius: [5, 5, 0, 0],
padding: [0, 0, 0, 0],
width: '0%'
},
t: {
align: 'center'
}
}
},
leaves: {
label: {
position: 'right',
verticalAlign: 'middle',
align: 'left'
}
},
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750
}
]
});
myChart.setOption(option = getOption(data));
});
}
@ -238,5 +135,6 @@
});
})
</script>
</body>
</html>