mirror of
https://gitee.com/huoyo/ko-time.git
synced 2025-12-06 16:58:26 +08:00
cherry-pick from spring2:v2.5.0
This commit is contained in:
parent
73efa549ca
commit
eb0e0c26d4
@ -0,0 +1,87 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.KoResult;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
import cn.langpy.kotime.service.metric.ClassInfoService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/classes")
|
||||||
|
public class KoClassController {
|
||||||
|
private static Logger log = Logger.getLogger(KoClassController.class.toString());
|
||||||
|
|
||||||
|
@GetMapping("/usage")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult usage() {
|
||||||
|
ClassInfoService instance = SystemService.getInstance(ClassInfoService.class);
|
||||||
|
return KoResult.success(instance.getClassUsage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{className}/replace")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult updateClass(@RequestParam("classFile") MultipartFile classFile, @PathVariable("className") String className) {
|
||||||
|
if (classFile == null || classFile.isEmpty()) {
|
||||||
|
return KoResult.failed("文件不能为空");
|
||||||
|
}
|
||||||
|
if (!StringUtils.hasText(className)) {
|
||||||
|
return KoResult.failed("类名不能为空");
|
||||||
|
}
|
||||||
|
className = className.trim();
|
||||||
|
File file = null;
|
||||||
|
try {
|
||||||
|
String originalFilename = classFile.getOriginalFilename();
|
||||||
|
if (!originalFilename.endsWith(".class")) {
|
||||||
|
return KoResult.failed("仅支持.class文件");
|
||||||
|
}
|
||||||
|
String[] filename = originalFilename.split("\\.");
|
||||||
|
String substring = className.substring(className.lastIndexOf(".") + 1);
|
||||||
|
if (!substring.equals(filename[0])) {
|
||||||
|
return KoResult.failed("请确认类名是否正确");
|
||||||
|
}
|
||||||
|
file = uploadFile(classFile.getBytes(), filename[0]);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.severe("Error class file!");
|
||||||
|
return KoResult.failed("无法解析文件");
|
||||||
|
}
|
||||||
|
final ClassInfoService classService = SystemService.getInstance(ClassInfoService.class);
|
||||||
|
classService.updateClass(className, file.getAbsolutePath());
|
||||||
|
file.deleteOnExit();
|
||||||
|
return KoResult.success("更新成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static File uploadFile(byte[] file, String fileName) throws IOException {
|
||||||
|
FileOutputStream out = null;
|
||||||
|
try {
|
||||||
|
File targetFile = File.createTempFile(fileName, ".class", new File(System.getProperty("java.io.tmpdir")));
|
||||||
|
out = new FileOutputStream(targetFile.getAbsolutePath());
|
||||||
|
out.write(file);
|
||||||
|
out.flush();
|
||||||
|
return targetFile;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.severe("" + e);
|
||||||
|
} finally {
|
||||||
|
if (out != null) {
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.config.DefaultConfig;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.model.KoResult;
|
||||||
|
import cn.langpy.kotime.util.Context;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/configs")
|
||||||
|
public class KoConfigController {
|
||||||
|
private static Logger log = Logger.getLogger(KoConfigController.class.toString());
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult getConfig() {
|
||||||
|
DefaultConfig config = Context.getConfig();
|
||||||
|
return KoResult.success(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult updateConfig(@RequestBody DefaultConfig config) {
|
||||||
|
DefaultConfig koTimeConfig = Context.getConfig();
|
||||||
|
if (config.getEnable() != null) {
|
||||||
|
koTimeConfig.setEnable(config.getEnable());
|
||||||
|
}
|
||||||
|
if (config.getExceptionEnable() != null) {
|
||||||
|
koTimeConfig.setExceptionEnable(config.getExceptionEnable());
|
||||||
|
}
|
||||||
|
if (config.getLogEnable() != null) {
|
||||||
|
koTimeConfig.setLogEnable(config.getLogEnable());
|
||||||
|
}
|
||||||
|
if (config.getMailEnable() != null) {
|
||||||
|
koTimeConfig.setMailEnable(config.getMailEnable());
|
||||||
|
}
|
||||||
|
if (config.getAbbreviationEnable() != null) {
|
||||||
|
koTimeConfig.setAbbreviationEnable(config.getAbbreviationEnable());
|
||||||
|
}
|
||||||
|
if (config.getThreshold() != null) {
|
||||||
|
koTimeConfig.setThreshold(config.getThreshold());
|
||||||
|
}
|
||||||
|
if (config.getLanguage() != null) {
|
||||||
|
koTimeConfig.setLanguage(config.getLanguage());
|
||||||
|
}
|
||||||
|
return KoResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.KoResult;
|
||||||
|
import cn.langpy.kotime.service.metric.CpuMetricService;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/cpus")
|
||||||
|
public class KoCpuUsageController {
|
||||||
|
private static Logger log = Logger.getLogger(KoCpuUsageController.class.toString());
|
||||||
|
|
||||||
|
@GetMapping("/usage")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult usage() {
|
||||||
|
CpuMetricService instance = SystemService.getInstance(CpuMetricService.class);
|
||||||
|
return KoResult.success(instance.getCpuUsage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.*;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.util.Context;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/dynamicProperties")
|
||||||
|
public class KoDynamicPropertyController {
|
||||||
|
private static Logger log = Logger.getLogger(KoDynamicPropertyController.class.toString());
|
||||||
|
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult updateDynamicProperties(@RequestBody TextParam textParam) {
|
||||||
|
if (!StringUtils.hasText(textParam.getText())) {
|
||||||
|
return KoResult.failed("更新失败");
|
||||||
|
}
|
||||||
|
String[] textSplit = textParam.getText().trim().split("\n");
|
||||||
|
Properties dynamicProperties = Context.getDynamicProperties();
|
||||||
|
for (String line : textSplit) {
|
||||||
|
line = line.trim();
|
||||||
|
if (line.length()==0 || line.startsWith("#") || line.startsWith("//")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int i = line.indexOf("=");
|
||||||
|
if (i<1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String propertyStr = line.substring(0, i).trim();
|
||||||
|
String valueStr = line.substring(i+1).trim();
|
||||||
|
log.info("updated property: "+propertyStr+"=("+dynamicProperties.get(propertyStr)+"->"+valueStr+")");
|
||||||
|
dynamicProperties.setProperty(propertyStr,valueStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return KoResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult getDynamicProperties() {
|
||||||
|
Properties dynamicProperties = Context.getDynamicProperties();
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (String key : dynamicProperties.stringPropertyNames()) {
|
||||||
|
String value = dynamicProperties.getProperty(key);
|
||||||
|
if (value!=null) {
|
||||||
|
stringBuilder.append(key+"="+value+"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return KoResult.success(stringBuilder.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.*;
|
||||||
|
import cn.langpy.kotime.service.GraphService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/exceptions")
|
||||||
|
public class KoExceptionController {
|
||||||
|
private static Logger log = Logger.getLogger(KoExceptionController.class.toString());
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult getExceptions() {
|
||||||
|
GraphService graphService = GraphService.getInstance();
|
||||||
|
List<ExceptionNode> exceptionList = graphService.getExceptions();
|
||||||
|
return KoResult.success(exceptionList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{exceptionId}/details")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult getMethodsByExceptionId(@PathVariable("exceptionId") String exceptionId, String message) {
|
||||||
|
GraphService graphService = GraphService.getInstance();
|
||||||
|
List<ExceptionInfo> exceptionInfos = graphService.getExceptionInfos(exceptionId, message);
|
||||||
|
return KoResult.success(exceptionInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.KoResult;
|
||||||
|
import cn.langpy.kotime.service.metric.GcMetricService;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/gcs")
|
||||||
|
public class KoGcUsageController {
|
||||||
|
private static Logger log = Logger.getLogger(KoGcUsageController.class.toString());
|
||||||
|
|
||||||
|
@GetMapping("/usage")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult usage() {
|
||||||
|
GcMetricService instance = SystemService.getInstance(GcMetricService.class);
|
||||||
|
return KoResult.success(instance.getGcUsage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,7 +1,9 @@
|
|||||||
package cn.langpy.kotime.controller;
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
import cn.langpy.kotime.constant.KoConstant;
|
import cn.langpy.kotime.constant.KoConstant;
|
||||||
import cn.langpy.kotime.model.*;
|
import cn.langpy.kotime.model.*;
|
||||||
|
import cn.langpy.kotime.service.GraphService;
|
||||||
import cn.langpy.kotime.util.Context;
|
import cn.langpy.kotime.util.Context;
|
||||||
import cn.langpy.kotime.util.InvalidAuthInfoException;
|
import cn.langpy.kotime.util.InvalidAuthInfoException;
|
||||||
import cn.langpy.kotime.util.KoUtil;
|
import cn.langpy.kotime.util.KoUtil;
|
||||||
@ -44,26 +46,22 @@ public class KoInitController {
|
|||||||
|
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Map login(@RequestBody UserInfo userInfo) {
|
public KoResult login(@RequestBody UserInfo userInfo) {
|
||||||
if (null == userInfo || !StringUtils.hasText(userInfo.getUserName()) || !StringUtils.hasText(userInfo.getPassword())) {
|
if (null == userInfo || !StringUtils.hasText(userInfo.getUserName()) || !StringUtils.hasText(userInfo.getPassword())) {
|
||||||
throw new InvalidAuthInfoException("failed to login for kotime,please fill userName and password!");
|
throw new InvalidAuthInfoException("failed to login for kotime,please fill userName and password!");
|
||||||
}
|
}
|
||||||
Map map = new HashMap();
|
|
||||||
if (userName.equals(userInfo.getUserName()) && password.equals(userInfo.getPassword())) {
|
if (userName.equals(userInfo.getUserName()) && password.equals(userInfo.getPassword())) {
|
||||||
String token = KoUtil.login(userInfo.getUserName());
|
String token = KoUtil.login(userInfo.getUserName());
|
||||||
map.put("state", 1);
|
Map map = new HashMap();
|
||||||
map.put("token", token);
|
map.put("token", token);
|
||||||
return map;
|
return KoResult.success(map);
|
||||||
}
|
}
|
||||||
map.put("state", 0);
|
return KoResult.failed("登录失败");
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/isLogin")
|
@GetMapping("/isLogin")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Map isLogin(String kotoken) {
|
public KoResult isLogin(String kotoken) {
|
||||||
Map map = new HashMap();
|
|
||||||
map.put("state", 1);
|
|
||||||
boolean checkLogin = false;
|
boolean checkLogin = false;
|
||||||
if (StringUtils.hasText(kotoken)) {
|
if (StringUtils.hasText(kotoken)) {
|
||||||
if (kotoken.equals(Context.getConfig().getStaticToken())) {
|
if (kotoken.equals(Context.getConfig().getStaticToken())) {
|
||||||
@ -72,8 +70,18 @@ public class KoInitController {
|
|||||||
checkLogin = KoUtil.isLogin(kotoken);
|
checkLogin = KoUtil.isLogin(kotoken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Map map = new HashMap();
|
||||||
map.put("isLogin", checkLogin ? 1 : 0);
|
map.put("isLogin", checkLogin ? 1 : 0);
|
||||||
return map;
|
return KoResult.success(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/clearData")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult clearData() {
|
||||||
|
GraphService graphService = GraphService.getInstance();
|
||||||
|
graphService.clearAll();
|
||||||
|
return KoResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,118 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.KoResult;
|
||||||
|
import cn.langpy.kotime.model.MethodInfo;
|
||||||
|
import cn.langpy.kotime.model.ParamMetric;
|
||||||
|
import cn.langpy.kotime.model.SystemStatistic;
|
||||||
|
import cn.langpy.kotime.service.GraphService;
|
||||||
|
import cn.langpy.kotime.util.Context;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/interfaces")
|
||||||
|
public class KoInterfaceController {
|
||||||
|
private static Logger log = Logger.getLogger(KoInterfaceController.class.toString());
|
||||||
|
|
||||||
|
@GetMapping("/usage")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult usage() {
|
||||||
|
GraphService graphService = GraphService.getInstance();
|
||||||
|
SystemStatistic system = graphService.getRunStatistic();
|
||||||
|
return KoResult.success(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult<List<MethodInfo>> getInterfaces(String question, String orderBy, String sort) {
|
||||||
|
GraphService graphService = GraphService.getInstance();
|
||||||
|
List<MethodInfo> list = null;
|
||||||
|
if (StringUtils.hasText(question)) {
|
||||||
|
list = graphService.searchMethods(question);
|
||||||
|
} else {
|
||||||
|
list = graphService.getControllers();
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(list, (o1, o2) -> {
|
||||||
|
int sortValue = -1;
|
||||||
|
if ("asc".equals(sort)) {
|
||||||
|
sortValue = 1;
|
||||||
|
}
|
||||||
|
if ("callNum".equals(orderBy)) {
|
||||||
|
return o1.getCallNum().compareTo(o2.getCallNum()) * sortValue;
|
||||||
|
} else {
|
||||||
|
return o1.getAvgRunTime().compareTo(o2.getAvgRunTime()) * sortValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return KoResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public void export(String question, String orderBy, String sort, HttpServletResponse response) {
|
||||||
|
List<MethodInfo> apis = getInterfaces(question, orderBy, sort).getContent();
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
response.addHeader("Content-Disposition", "attachment; filename=interfaces.csv");
|
||||||
|
|
||||||
|
try (OutputStream out = response.getOutputStream();
|
||||||
|
BufferedOutputStream bufferedOut = new BufferedOutputStream(out)) {
|
||||||
|
String line = "序号,类名,方法名,路由,平均响应(ms),调用次数\n";
|
||||||
|
if ("english".equals(Context.getConfig().getLanguage())) {
|
||||||
|
line = "No,ClassName,Method,Route,Avg(ms),CallNum\n";
|
||||||
|
}
|
||||||
|
bufferedOut.write(line.getBytes("utf-8"));
|
||||||
|
for (int i = 0; i < apis.size(); i++) {
|
||||||
|
MethodInfo methodInfo = apis.get(i);
|
||||||
|
line = (i + 1) + "," + methodInfo.getClassName() + "," + methodInfo.getMethodName() + "()," + methodInfo.getRouteName() + "," + methodInfo.getAvgRunTime() + "," + methodInfo.getCallNum() + "\n";
|
||||||
|
bufferedOut.write(line.getBytes("utf-8"));
|
||||||
|
}
|
||||||
|
bufferedOut.flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/searchCondidate")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult<List<String>> searchCondidate(String question) {
|
||||||
|
GraphService graphService = GraphService.getInstance();
|
||||||
|
List<String> list = graphService.getCondidates(question);
|
||||||
|
return KoResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{methodId}/paramMetric")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult<Map<String, ParamMetric>> paramMetric(@PathVariable("methodId") String methodId) {
|
||||||
|
GraphService graphService = GraphService.getInstance();
|
||||||
|
Map<String, ParamMetric> list = graphService.getMethodParamGraph(methodId);
|
||||||
|
return KoResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{methodId}/tree")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult getTree(@PathVariable("methodId") String methodId) {
|
||||||
|
GraphService graphService = GraphService.getInstance();
|
||||||
|
MethodInfo tree = graphService.getTree(methodId);
|
||||||
|
return KoResult.success(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.KoResult;
|
||||||
|
import cn.langpy.kotime.service.metric.JvmSpaceMetricService;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/jvmSpaces")
|
||||||
|
public class KoJvmSpaceController {
|
||||||
|
private static Logger log = Logger.getLogger(KoJvmSpaceController.class.toString());
|
||||||
|
|
||||||
|
@GetMapping("/edenSpace")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult edenSpace() {
|
||||||
|
JvmSpaceMetricService instance = SystemService.getInstance(JvmSpaceMetricService.class);
|
||||||
|
return KoResult.success(instance.getEdenSpaceInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/survivorSpace")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult survivorSpace() {
|
||||||
|
JvmSpaceMetricService instance = SystemService.getInstance(JvmSpaceMetricService.class);
|
||||||
|
return KoResult.success(instance.getSurvivorSpaceInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/oldGen")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult oldGen() {
|
||||||
|
JvmSpaceMetricService instance = SystemService.getInstance(JvmSpaceMetricService.class);
|
||||||
|
return KoResult.success(instance.getOldGenInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/metaspace")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult metaspace() {
|
||||||
|
JvmSpaceMetricService instance = SystemService.getInstance(JvmSpaceMetricService.class);
|
||||||
|
return KoResult.success(instance.getMetaspaceInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.*;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
import cn.langpy.kotime.service.metric.MemoryMetricService;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/memories")
|
||||||
|
public class KoMemoryController {
|
||||||
|
private static Logger log = Logger.getLogger(KoMemoryController.class.toString());
|
||||||
|
|
||||||
|
@GetMapping("/heap")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult heap() {
|
||||||
|
MemoryMetricService instance = SystemService.getInstance(MemoryMetricService.class);
|
||||||
|
JvmMemoryInfo heapMemoryInfo = instance.getHeapMemoryInfo();
|
||||||
|
return KoResult.success(heapMemoryInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/nonHeap")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult nonHeap() {
|
||||||
|
MemoryMetricService instance = SystemService.getInstance(MemoryMetricService.class);
|
||||||
|
JvmMemoryInfo heapMemoryInfo = instance.getNonHeapMemoryInfo();
|
||||||
|
return KoResult.success(heapMemoryInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/physical")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult physical() {
|
||||||
|
MemoryMetricService instance = SystemService.getInstance(MemoryMetricService.class);
|
||||||
|
PhysicalMemoryInfo heapMemoryInfo = instance.getPhysicalMemoryInfo();
|
||||||
|
return KoResult.success(heapMemoryInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/heap/export")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public void heapExport(Boolean live, HttpServletResponse response) {
|
||||||
|
live = live == null ? false : live;
|
||||||
|
MemoryMetricService instance = SystemService.getInstance(MemoryMetricService.class);
|
||||||
|
String heapDumpFile = instance.getHeapDumpFile(live);
|
||||||
|
if (heapDumpFile == null) {
|
||||||
|
throw new RuntimeException("Can not dumpheap file!");
|
||||||
|
}
|
||||||
|
log.info(heapDumpFile);
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||||
|
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + instance.getHeapDumpFileName(live));
|
||||||
|
try (OutputStream out = response.getOutputStream();
|
||||||
|
BufferedOutputStream bufferedOut = new BufferedOutputStream(out);
|
||||||
|
FileInputStream fileInputStream = new FileInputStream(heapDumpFile);
|
||||||
|
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream)) {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
|
||||||
|
bufferedOut.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
bufferedOut.flush();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
|
import cn.langpy.kotime.model.KoResult;
|
||||||
|
import cn.langpy.kotime.model.ThreadInfo;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
import cn.langpy.kotime.service.metric.ThreadMetricService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static cn.langpy.kotime.model.ThreadInfo.COMPARATOR;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime/threads")
|
||||||
|
public class KoThreadController {
|
||||||
|
private static Logger log = Logger.getLogger(KoThreadController.class.toString());
|
||||||
|
|
||||||
|
@GetMapping("/usage")
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult usage() {
|
||||||
|
ThreadMetricService instance = SystemService.getInstance(ThreadMetricService.class);
|
||||||
|
return KoResult.success(instance.getThreadUsage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@ResponseBody
|
||||||
|
@Auth
|
||||||
|
public KoResult threads(String state) {
|
||||||
|
ThreadMetricService instance = SystemService.getInstance(ThreadMetricService.class);
|
||||||
|
List<ThreadInfo> threads = instance.getThreads();
|
||||||
|
threads = threads.stream().sorted(COMPARATOR).collect(Collectors.toList());
|
||||||
|
|
||||||
|
Map<String, Long> stateCounting = threads.stream().collect(Collectors.groupingBy(ThreadInfo::getState, Collectors.counting()));
|
||||||
|
stateCounting.put("all", (long) threads.size());
|
||||||
|
|
||||||
|
Map map = new HashMap();
|
||||||
|
map.put("statistics", stateCounting);
|
||||||
|
if (StringUtils.hasText(state)) {
|
||||||
|
threads = threads.stream().filter(a -> a.getState().equals(state)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
map.put("threads", threads);
|
||||||
|
return KoResult.success(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,376 +0,0 @@
|
|||||||
package cn.langpy.kotime.controller;
|
|
||||||
|
|
||||||
import cn.langpy.kotime.annotation.Auth;
|
|
||||||
import cn.langpy.kotime.config.DefaultConfig;
|
|
||||||
import cn.langpy.kotime.model.*;
|
|
||||||
import cn.langpy.kotime.service.*;
|
|
||||||
import cn.langpy.kotime.util.Context;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static cn.langpy.kotime.model.ThreadInfo.COMPARATOR;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* zhangchang
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/koTime")
|
|
||||||
public class KoTimeController {
|
|
||||||
private static Logger log = Logger.getLogger(KoTimeController.class.toString());
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/getConfig")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public DefaultConfig getConfig() {
|
|
||||||
DefaultConfig config = Context.getConfig();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getStatistic")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public SystemStatistic getStatistic() {
|
|
||||||
GraphService graphService = GraphService.getInstance();
|
|
||||||
SystemStatistic system = graphService.getRunStatistic();
|
|
||||||
return system;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getApis")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public List<MethodInfo> getApis(String question,String orderBy,String sort) {
|
|
||||||
GraphService graphService = GraphService.getInstance();
|
|
||||||
List<MethodInfo> list = null;
|
|
||||||
if (StringUtils.hasText(question)) {
|
|
||||||
list = graphService.searchMethods(question);
|
|
||||||
} else {
|
|
||||||
list = graphService.getControllers();
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(list, (o1, o2) -> {
|
|
||||||
int sortValue = -1;
|
|
||||||
if ("asc".equals(sort)) {
|
|
||||||
sortValue = 1;
|
|
||||||
}
|
|
||||||
if ("callNum".equals(orderBy)) {
|
|
||||||
return o1.getCallNum().compareTo(o2.getCallNum())* sortValue;
|
|
||||||
}else {
|
|
||||||
return o1.getAvgRunTime().compareTo(o2.getAvgRunTime())* sortValue;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/exportApis")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public void exportApis(String question, String orderBy, String sort, HttpServletResponse response) {
|
|
||||||
List<MethodInfo> apis = getApis(question, orderBy, sort);
|
|
||||||
response.setCharacterEncoding("utf-8");
|
|
||||||
response.addHeader("Content-Disposition", "attachment; filename=interfaces.csv");
|
|
||||||
|
|
||||||
try( OutputStream out = response.getOutputStream();
|
|
||||||
BufferedOutputStream bufferedOut = new BufferedOutputStream(out)){
|
|
||||||
String line = "序号,类名,方法名,路由,平均响应(ms),调用次数\n";
|
|
||||||
if ("english".equals(Context.getConfig().getLanguage())) {
|
|
||||||
line = "No,ClassName,Method,Route,Avg(ms),CallNum\n";
|
|
||||||
}
|
|
||||||
bufferedOut.write(line.getBytes("utf-8"));
|
|
||||||
for (int i = 0; i < apis.size(); i++) {
|
|
||||||
MethodInfo methodInfo = apis.get(i);
|
|
||||||
line = (i+1)+","+methodInfo.getClassName()+","+methodInfo.getMethodName()+"(),"+methodInfo.getRouteName()+","+methodInfo.getAvgRunTime()+","+methodInfo.getCallNum()+"\n";
|
|
||||||
bufferedOut.write(line.getBytes("utf-8"));
|
|
||||||
}
|
|
||||||
bufferedOut.flush();
|
|
||||||
}catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/getParamGraph")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public Map<String, ParamMetric> getParamGraph(String methodId) {
|
|
||||||
GraphService graphService = GraphService.getInstance();
|
|
||||||
Map<String, ParamMetric> list = graphService.getMethodParamGraph(methodId);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getApiTips")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public List<String> getApiTips(String question) {
|
|
||||||
GraphService graphService = GraphService.getInstance();
|
|
||||||
List<String> list = graphService.getCondidates(question);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/getExceptions")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public List<ExceptionNode> getExceptions() {
|
|
||||||
GraphService graphService = GraphService.getInstance();
|
|
||||||
List<ExceptionNode> exceptionList = graphService.getExceptions();
|
|
||||||
return exceptionList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getTree")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public MethodInfo getTree(String methodName) {
|
|
||||||
GraphService graphService = GraphService.getInstance();
|
|
||||||
MethodInfo tree = graphService.getTree(methodName);
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getMethodsByExceptionId")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public List<ExceptionInfo> getMethodsByExceptionId(String exceptionId, String message) {
|
|
||||||
GraphService graphService = GraphService.getInstance();
|
|
||||||
List<ExceptionInfo> exceptionInfos = graphService.getExceptionInfos(exceptionId, message);
|
|
||||||
return exceptionInfos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/updateConfig")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public boolean updateConfig(@RequestBody DefaultConfig config) {
|
|
||||||
DefaultConfig koTimeConfig = Context.getConfig();
|
|
||||||
if (config.getEnable() != null) {
|
|
||||||
koTimeConfig.setEnable(config.getEnable());
|
|
||||||
}
|
|
||||||
if (config.getExceptionEnable() != null) {
|
|
||||||
koTimeConfig.setExceptionEnable(config.getExceptionEnable());
|
|
||||||
}
|
|
||||||
if (config.getLogEnable() != null) {
|
|
||||||
koTimeConfig.setLogEnable(config.getLogEnable());
|
|
||||||
}
|
|
||||||
if (config.getMailEnable() != null) {
|
|
||||||
koTimeConfig.setMailEnable(config.getMailEnable());
|
|
||||||
}
|
|
||||||
if (config.getAbbreviationEnable() != null) {
|
|
||||||
koTimeConfig.setAbbreviationEnable(config.getAbbreviationEnable());
|
|
||||||
}
|
|
||||||
if (config.getThreshold() != null) {
|
|
||||||
koTimeConfig.setThreshold(config.getThreshold());
|
|
||||||
}
|
|
||||||
if (config.getLanguage() != null) {
|
|
||||||
koTimeConfig.setLanguage(config.getLanguage());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/updateClass")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public Map updateClass(@RequestParam("classFile") MultipartFile classFile, String className) {
|
|
||||||
Map map = new HashMap();
|
|
||||||
if (classFile == null || classFile.isEmpty()) {
|
|
||||||
map.put("state", 0);
|
|
||||||
map.put("message", "文件不能为空");
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
if (!StringUtils.hasText(className)) {
|
|
||||||
map.put("state", 0);
|
|
||||||
map.put("message", "类名不能为空");
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
className = className.trim();
|
|
||||||
File file = null;
|
|
||||||
try {
|
|
||||||
String originalFilename = classFile.getOriginalFilename();
|
|
||||||
if (!originalFilename.endsWith(".class")) {
|
|
||||||
map.put("state", 0);
|
|
||||||
map.put("message", "仅支持.class文件");
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
String[] filename = originalFilename.split("\\.");
|
|
||||||
String substring = className.substring(className.lastIndexOf(".") + 1);
|
|
||||||
if (!substring.equals(filename[0])) {
|
|
||||||
map.put("state", 0);
|
|
||||||
map.put("message", "请确认类名是否正确");
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
file = uploadFile(classFile.getBytes(), filename[0]);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.severe("Error class file!");
|
|
||||||
map.put("state", 0);
|
|
||||||
map.put("message", "无法解析文件");
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
final ClassService classService = ClassService.getInstance();
|
|
||||||
classService.updateClass(className, file.getAbsolutePath());
|
|
||||||
file.deleteOnExit();
|
|
||||||
|
|
||||||
map.put("state", 1);
|
|
||||||
map.put("message", "更新成功");
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static File uploadFile(byte[] file, String fileName) throws IOException {
|
|
||||||
FileOutputStream out = null;
|
|
||||||
try {
|
|
||||||
File targetFile = File.createTempFile(fileName, ".class", new File(System.getProperty("java.io.tmpdir")));
|
|
||||||
out = new FileOutputStream(targetFile.getAbsolutePath());
|
|
||||||
out.write(file);
|
|
||||||
out.flush();
|
|
||||||
return targetFile;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.severe("" + e);
|
|
||||||
} finally {
|
|
||||||
if (out != null) {
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getCpuInfo")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public CpuInfo getCpuInfo() {
|
|
||||||
SysUsageService usageService = SysUsageService.newInstance();
|
|
||||||
CpuInfo cpuInfo = usageService.getCpuInfo();
|
|
||||||
return cpuInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getHeapMemoryInfo")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public HeapMemoryInfo getHeapMemoryInfo() {
|
|
||||||
SysUsageService usageService = SysUsageService.newInstance();
|
|
||||||
HeapMemoryInfo heapMemoryInfo = usageService.getHeapMemoryInfo();
|
|
||||||
return heapMemoryInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/dumpHeap")
|
|
||||||
@ResponseBody
|
|
||||||
// @Auth
|
|
||||||
public void dumpHeap(Boolean live, HttpServletResponse response) {
|
|
||||||
live = live==null?false:live;
|
|
||||||
HeapDumpService heapDumpService = HeapDumpService.newInstance();
|
|
||||||
String heapDumpFile = heapDumpService.getHeapDumpFile(live);
|
|
||||||
if (heapDumpFile == null) {
|
|
||||||
throw new RuntimeException("Can not dumpheap file!");
|
|
||||||
}
|
|
||||||
log.info(heapDumpFile);
|
|
||||||
response.setCharacterEncoding("utf-8");
|
|
||||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
|
||||||
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+heapDumpService.getHeapDumpFileName(live));
|
|
||||||
try( OutputStream out = response.getOutputStream();
|
|
||||||
BufferedOutputStream bufferedOut = new BufferedOutputStream(out);
|
|
||||||
FileInputStream fileInputStream = new FileInputStream(heapDumpFile);
|
|
||||||
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream)){
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
|
|
||||||
bufferedOut.write(buffer,0,bytesRead);
|
|
||||||
}
|
|
||||||
bufferedOut.flush();
|
|
||||||
|
|
||||||
}catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getPhysicalMemoryInfo")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public PhysicalMemoryInfo getPhysicalMemoryInfo() {
|
|
||||||
SysUsageService usageService = SysUsageService.newInstance();
|
|
||||||
PhysicalMemoryInfo physicalMemoryInfo = usageService.getPhysicalMemoryInfo();
|
|
||||||
return physicalMemoryInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/clearData")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public boolean clearData() {
|
|
||||||
GraphService graphService = GraphService.getInstance();
|
|
||||||
graphService.clearAll();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getThreadsInfo")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public Map getThreadsInfo(String state) {
|
|
||||||
ThreadUsageService usageService = ThreadUsageService.newInstance();
|
|
||||||
List<ThreadInfo> threads = usageService.getThreads();
|
|
||||||
threads = threads.stream().sorted(COMPARATOR).collect(Collectors.toList());
|
|
||||||
|
|
||||||
Map<String, Long> stateCounting = threads.stream().collect(Collectors.groupingBy(ThreadInfo::getState, Collectors.counting()));
|
|
||||||
stateCounting.put("all", (long) threads.size());
|
|
||||||
|
|
||||||
Map map = new HashMap();
|
|
||||||
map.put("statistics", stateCounting);
|
|
||||||
if (StringUtils.hasText(state)) {
|
|
||||||
threads = threads.stream().filter(a -> a.getState().equals(state)).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
map.put("threads", threads);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/updateDynamicProperties")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public boolean updateDynamicProperties(@RequestBody TextParam textParam) {
|
|
||||||
if (!StringUtils.hasText(textParam.getText())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String[] textSplit = textParam.getText().trim().split("\n");
|
|
||||||
Properties dynamicProperties = Context.getDynamicProperties();
|
|
||||||
for (String line : textSplit) {
|
|
||||||
line = line.trim();
|
|
||||||
if (line.length() == 0 || line.startsWith("#") || line.startsWith("//")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int i = line.indexOf("=");
|
|
||||||
if (i < 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String propertyStr = line.substring(0, i).trim();
|
|
||||||
String valueStr = line.substring(i + 1).trim();
|
|
||||||
log.info("updated property: " + propertyStr + "=(" + dynamicProperties.get(propertyStr) + "->" + valueStr + ")");
|
|
||||||
dynamicProperties.setProperty(propertyStr, valueStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getDynamicProperties")
|
|
||||||
@ResponseBody
|
|
||||||
@Auth
|
|
||||||
public Map getDynamicProperties() {
|
|
||||||
Map map = new HashMap();
|
|
||||||
map.put("state", 0);
|
|
||||||
map.put("message", "文件不能为空");
|
|
||||||
Properties dynamicProperties = Context.getDynamicProperties();
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
for (String key : dynamicProperties.stringPropertyNames()) {
|
|
||||||
String value = dynamicProperties.getProperty(key);
|
|
||||||
if (value != null) {
|
|
||||||
stringBuilder.append(key + "=" + value + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
map.put("data", stringBuilder.toString());
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -14,6 +14,7 @@ import java.sql.Connection;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
@ -328,6 +329,16 @@ public class DataBase implements GraphService {
|
|||||||
systemStatistic.setMaxRunTime(max);
|
systemStatistic.setMaxRunTime(max);
|
||||||
systemStatistic.setMinRunTime(min);
|
systemStatistic.setMinRunTime(min);
|
||||||
systemStatistic.setAvgRunTime(avg);
|
systemStatistic.setAvgRunTime(avg);
|
||||||
|
|
||||||
|
|
||||||
|
int maxCallNum = controllerApis.stream().map(api -> api.getCallNum()).max(Integer::compareTo).get();
|
||||||
|
int minCallNum = controllerApis.stream().map(api -> api.getCallNum()).min(Integer::compareTo).get();
|
||||||
|
double avgCallNum = controllerApis.stream().map(api -> api.getCallNum()).collect(Collectors.averagingInt(Integer::intValue));
|
||||||
|
BigDecimal bgCallNum = BigDecimal.valueOf(avgCallNum);
|
||||||
|
avgCallNum = bgCallNum.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||||
|
systemStatistic.setMaxCallNum(maxCallNum);
|
||||||
|
systemStatistic.setMinCallNum(minCallNum);
|
||||||
|
systemStatistic.setAvgCallNum(avgCallNum);
|
||||||
return systemStatistic;
|
return systemStatistic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -377,6 +377,15 @@ public class MemoryBase implements GraphService {
|
|||||||
systemStatistic.setMaxRunTime(max);
|
systemStatistic.setMaxRunTime(max);
|
||||||
systemStatistic.setMinRunTime(min);
|
systemStatistic.setMinRunTime(min);
|
||||||
systemStatistic.setAvgRunTime(avg);
|
systemStatistic.setAvgRunTime(avg);
|
||||||
|
|
||||||
|
int maxCallNum = controllerApis.stream().map(api -> api.getCallNum()).max(Integer::compareTo).get();
|
||||||
|
int minCallNum = controllerApis.stream().map(api -> api.getCallNum()).min(Integer::compareTo).get();
|
||||||
|
double avgCallNum = controllerApis.stream().map(api -> api.getCallNum()).collect(Collectors.averagingInt(Integer::intValue));
|
||||||
|
BigDecimal bgCallNum = BigDecimal.valueOf(avgCallNum);
|
||||||
|
avgCallNum = bgCallNum.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||||
|
systemStatistic.setMaxCallNum(maxCallNum);
|
||||||
|
systemStatistic.setMinCallNum(minCallNum);
|
||||||
|
systemStatistic.setAvgCallNum(avgCallNum);
|
||||||
return systemStatistic;
|
return systemStatistic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -411,6 +411,16 @@ public class RedisBase implements GraphService {
|
|||||||
systemStatistic.setMaxRunTime(max);
|
systemStatistic.setMaxRunTime(max);
|
||||||
systemStatistic.setMinRunTime(min);
|
systemStatistic.setMinRunTime(min);
|
||||||
systemStatistic.setAvgRunTime(avg);
|
systemStatistic.setAvgRunTime(avg);
|
||||||
|
|
||||||
|
|
||||||
|
int maxCallNum = controllerApis.stream().map(api -> api.getCallNum()).max(Integer::compareTo).get();
|
||||||
|
int minCallNum = controllerApis.stream().map(api -> api.getCallNum()).min(Integer::compareTo).get();
|
||||||
|
double avgCallNum = controllerApis.stream().map(api -> api.getCallNum()).collect(Collectors.averagingInt(Integer::intValue));
|
||||||
|
BigDecimal bgCallNum = BigDecimal.valueOf(avgCallNum);
|
||||||
|
avgCallNum = bgCallNum.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||||
|
systemStatistic.setMaxCallNum(maxCallNum);
|
||||||
|
systemStatistic.setMinCallNum(minCallNum);
|
||||||
|
systemStatistic.setAvgCallNum(avgCallNum);
|
||||||
return systemStatistic;
|
return systemStatistic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
src/main/java/cn/langpy/kotime/model/ClassUsage.java
Normal file
31
src/main/java/cn/langpy/kotime/model/ClassUsage.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package cn.langpy.kotime.model;
|
||||||
|
|
||||||
|
public class ClassUsage {
|
||||||
|
private Long totalClassNum;
|
||||||
|
private Integer currentClassNum;
|
||||||
|
private Long unloadedClassNum;
|
||||||
|
|
||||||
|
public Long getTotalClassNum() {
|
||||||
|
return totalClassNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalClassNum(Long totalClassNum) {
|
||||||
|
this.totalClassNum = totalClassNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCurrentClassNum() {
|
||||||
|
return currentClassNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentClassNum(Integer currentClassNum) {
|
||||||
|
this.currentClassNum = currentClassNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUnloadedClassNum() {
|
||||||
|
return unloadedClassNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnloadedClassNum(Long unloadedClassNum) {
|
||||||
|
this.unloadedClassNum = unloadedClassNum;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package cn.langpy.kotime.model;
|
package cn.langpy.kotime.model;
|
||||||
|
|
||||||
public class CpuInfo {
|
public class CpuUsage {
|
||||||
private Double systemLoad;
|
private Double systemLoad;
|
||||||
private Double userRate;
|
private Double userRate;
|
||||||
private Double sysRate;
|
private Double sysRate;
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package cn.langpy.kotime.model;
|
||||||
|
|
||||||
|
public class GarbageCollectionInfo {
|
||||||
|
private Integer youngGcNum;
|
||||||
|
private Long youngGcTime;
|
||||||
|
private Integer oldGcNum;
|
||||||
|
private Long oldGcNumTime;
|
||||||
|
|
||||||
|
public Integer getYoungGcNum() {
|
||||||
|
return youngGcNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYoungGcNum(Integer youngGcNum) {
|
||||||
|
this.youngGcNum = youngGcNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getYoungGcTime() {
|
||||||
|
return youngGcTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYoungGcTime(Long youngGcTime) {
|
||||||
|
this.youngGcTime = youngGcTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOldGcNum() {
|
||||||
|
return oldGcNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOldGcNum(Integer oldGcNum) {
|
||||||
|
this.oldGcNum = oldGcNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getOldGcNumTime() {
|
||||||
|
return oldGcNumTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOldGcNumTime(Long oldGcNumTime) {
|
||||||
|
this.oldGcNumTime = oldGcNumTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/main/java/cn/langpy/kotime/model/GcUsage.java
Normal file
49
src/main/java/cn/langpy/kotime/model/GcUsage.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package cn.langpy.kotime.model;
|
||||||
|
|
||||||
|
public class GcUsage {
|
||||||
|
private Long totalNum;
|
||||||
|
private Long minorNum;
|
||||||
|
private Long minorCostTime;
|
||||||
|
private Long fullNum;
|
||||||
|
private Long fullCostTime;
|
||||||
|
|
||||||
|
public Long getTotalNum() {
|
||||||
|
return totalNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalNum(Long totalNum) {
|
||||||
|
this.totalNum = totalNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMinorNum() {
|
||||||
|
return minorNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinorNum(Long minorNum) {
|
||||||
|
this.minorNum = minorNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMinorCostTime() {
|
||||||
|
return minorCostTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinorCostTime(Long minorCostTime) {
|
||||||
|
this.minorCostTime = minorCostTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getFullNum() {
|
||||||
|
return fullNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullNum(Long fullNum) {
|
||||||
|
this.fullNum = fullNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getFullCostTime() {
|
||||||
|
return fullCostTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullCostTime(Long fullCostTime) {
|
||||||
|
this.fullCostTime = fullCostTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package cn.langpy.kotime.model;
|
package cn.langpy.kotime.model;
|
||||||
|
|
||||||
public class HeapMemoryInfo {
|
public class JvmMemoryInfo {
|
||||||
private Long initValue;
|
private Long initValue;
|
||||||
private Long maxValue;
|
private Long maxValue;
|
||||||
private Long usedValue;
|
private Long usedValue;
|
||||||
58
src/main/java/cn/langpy/kotime/model/KoResult.java
Normal file
58
src/main/java/cn/langpy/kotime/model/KoResult.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package cn.langpy.kotime.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public class KoResult<T> {
|
||||||
|
private Integer state = 1;
|
||||||
|
private String message;
|
||||||
|
private T content;
|
||||||
|
|
||||||
|
|
||||||
|
public static KoResult failed(String message) {
|
||||||
|
KoResult result = new KoResult();
|
||||||
|
result.setState(0);
|
||||||
|
result.setMessage(message);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KoResult success(Object content) {
|
||||||
|
KoResult result = new KoResult();
|
||||||
|
result.setState(1);
|
||||||
|
result.setMessage("成功");
|
||||||
|
result.setContent(content);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KoResult success() {
|
||||||
|
KoResult result = new KoResult();
|
||||||
|
result.setState(1);
|
||||||
|
result.setMessage("成功");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(Integer state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(T content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,7 +9,9 @@ public class SystemStatistic {
|
|||||||
private Integer totalNum = 0 ;
|
private Integer totalNum = 0 ;
|
||||||
private Integer delayNum = 0;
|
private Integer delayNum = 0;
|
||||||
private Integer normalNum = 0;
|
private Integer normalNum = 0;
|
||||||
|
private Double avgCallNum = 0.0;
|
||||||
|
private Integer maxCallNum = 0;
|
||||||
|
private Integer minCallNum = 0;
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -66,6 +68,30 @@ public class SystemStatistic {
|
|||||||
this.normalNum = normalNum;
|
this.normalNum = normalNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Double getAvgCallNum() {
|
||||||
|
return avgCallNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvgCallNum(Double avgCallNum) {
|
||||||
|
this.avgCallNum = avgCallNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getMaxCallNum() {
|
||||||
|
return maxCallNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxCallNum(Integer maxCallNum) {
|
||||||
|
this.maxCallNum = maxCallNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getMinCallNum() {
|
||||||
|
return minCallNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinCallNum(Integer minCallNum) {
|
||||||
|
this.minCallNum = minCallNum;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SystemStatistic{" +
|
return "SystemStatistic{" +
|
||||||
|
|||||||
@ -14,10 +14,19 @@ public class ThreadInfo {
|
|||||||
private String state;
|
private String state;
|
||||||
private Boolean isInterrupted;
|
private Boolean isInterrupted;
|
||||||
private Boolean isDaemon;
|
private Boolean isDaemon;
|
||||||
|
private Boolean deadLock;
|
||||||
private Integer priority;
|
private Integer priority;
|
||||||
private BigDecimal cpuUsage;
|
private BigDecimal cpuUsage;
|
||||||
private List<StackTraceElement> stacks;
|
private List<StackTraceElement> stacks;
|
||||||
|
|
||||||
|
public Boolean getDeadLock() {
|
||||||
|
return this.deadLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeadLock(Boolean deadLock) {
|
||||||
|
this.deadLock = deadLock;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/main/java/cn/langpy/kotime/model/ThreadUsage.java
Normal file
31
src/main/java/cn/langpy/kotime/model/ThreadUsage.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package cn.langpy.kotime.model;
|
||||||
|
|
||||||
|
public class ThreadUsage {
|
||||||
|
private Integer totalNum;
|
||||||
|
private Integer runnableNum;
|
||||||
|
private Integer deadLockNum;
|
||||||
|
|
||||||
|
public Integer getTotalNum() {
|
||||||
|
return totalNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalNum(Integer totalNum) {
|
||||||
|
this.totalNum = totalNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRunnableNum() {
|
||||||
|
return runnableNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRunnableNum(Integer runnableNum) {
|
||||||
|
this.runnableNum = runnableNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getDeadLockNum() {
|
||||||
|
return deadLockNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeadLockNum(Integer deadLockNum) {
|
||||||
|
this.deadLockNum = deadLockNum;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package cn.langpy.kotime.service;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public interface ClassService {
|
|
||||||
void updateClass(String className, String classPath);
|
|
||||||
|
|
||||||
static ClassService getInstance() {
|
|
||||||
return ClassServiceFactory.getInstance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ClassServiceFactory {
|
|
||||||
private static Logger log = Logger.getLogger(ClassServiceFactory.class.toString());
|
|
||||||
|
|
||||||
private static ClassService instance = null;
|
|
||||||
|
|
||||||
public static ClassService getInstance() {
|
|
||||||
if (instance == null) {
|
|
||||||
synchronized (ClassServiceFactory.class) {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new JvmAttachClassService();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
package cn.langpy.kotime.service;
|
|
||||||
|
|
||||||
import com.sun.management.HotSpotDiagnosticMXBean;
|
|
||||||
|
|
||||||
import javax.management.MBeanServer;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class HeapDumpService {
|
|
||||||
private static final String STANDARD_DUMP_NAME = "kotime-heapdump-%s.hprof";
|
|
||||||
private static Logger log = Logger.getLogger(HeapDumpService.class.toString());
|
|
||||||
private static final String HotSpotDiagnosticName = "com.sun.management:type=HotSpotDiagnostic";
|
|
||||||
|
|
||||||
public static HeapDumpService newInstance() {
|
|
||||||
return new HeapDumpService();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHeapDumpFile(boolean live) {
|
|
||||||
String targetFile = System.getProperty("java.io.tmpdir")+File.separator+getHeapDumpFileName(live);
|
|
||||||
try {
|
|
||||||
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
|
||||||
HotSpotDiagnosticMXBean hotSpotDiagnostic = ManagementFactory.newPlatformMXBeanProxy(server, HotSpotDiagnosticName, HotSpotDiagnosticMXBean.class);
|
|
||||||
if (Files.exists(Paths.get(targetFile))) {
|
|
||||||
new File(targetFile).delete();
|
|
||||||
}
|
|
||||||
hotSpotDiagnostic.dumpHeap(targetFile, live);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
log.severe("Can not dump heap file!");
|
|
||||||
}
|
|
||||||
return targetFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHeapDumpFileName(boolean live) {
|
|
||||||
if (live) {
|
|
||||||
return String.format(STANDARD_DUMP_NAME, "live");
|
|
||||||
}
|
|
||||||
return String.format(STANDARD_DUMP_NAME, "all");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,144 +0,0 @@
|
|||||||
package cn.langpy.kotime.service;
|
|
||||||
|
|
||||||
import cn.langpy.kotime.model.CpuInfo;
|
|
||||||
import cn.langpy.kotime.model.HeapMemoryInfo;
|
|
||||||
import cn.langpy.kotime.model.PhysicalMemoryInfo;
|
|
||||||
import cn.langpy.kotime.util.Context;
|
|
||||||
import com.sun.management.OperatingSystemMXBean;
|
|
||||||
import oshi.SystemInfo;
|
|
||||||
import oshi.hardware.CentralProcessor;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.lang.management.MemoryMXBean;
|
|
||||||
import java.lang.management.MemoryUsage;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class SysUsageService {
|
|
||||||
private static Logger log = Logger.getLogger(SysUsageService.class.toString());
|
|
||||||
|
|
||||||
public static SysUsageService newInstance() {
|
|
||||||
return new SysUsageService();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CpuInfo getCpuInfo() {
|
|
||||||
SystemInfo systemInfo = new SystemInfo();
|
|
||||||
CentralProcessor processor = systemInfo.getHardware().getProcessor();
|
|
||||||
long[] prevTicks = processor.getSystemCpuLoadTicks();
|
|
||||||
try {
|
|
||||||
TimeUnit.SECONDS.sleep(1);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
long[] ticks = processor.getSystemCpuLoadTicks();
|
|
||||||
long nice = ticks[CentralProcessor.TickType.NICE.getIndex()]
|
|
||||||
- prevTicks[CentralProcessor.TickType.NICE.getIndex()];
|
|
||||||
|
|
||||||
long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()]
|
|
||||||
- prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
|
|
||||||
|
|
||||||
long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()]
|
|
||||||
- prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
|
|
||||||
|
|
||||||
long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()]
|
|
||||||
- prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
|
|
||||||
|
|
||||||
long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()]
|
|
||||||
- prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
|
|
||||||
|
|
||||||
long user = ticks[CentralProcessor.TickType.USER.getIndex()]
|
|
||||||
- prevTicks[CentralProcessor.TickType.USER.getIndex()];
|
|
||||||
|
|
||||||
long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()]
|
|
||||||
- prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
|
|
||||||
|
|
||||||
long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()]
|
|
||||||
- prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
|
|
||||||
|
|
||||||
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
|
|
||||||
CpuInfo cpuInfo = new CpuInfo();
|
|
||||||
cpuInfo.setLogicalNum(processor.getLogicalProcessorCount());
|
|
||||||
cpuInfo.setUserRate(user * 1.0 / totalCpu);
|
|
||||||
cpuInfo.setSysRate(cSys * 1.0 / totalCpu);
|
|
||||||
cpuInfo.setWaitRate(iowait * 1.0 / totalCpu);
|
|
||||||
cpuInfo.setSystemLoad(processor.getSystemCpuLoad(1000));
|
|
||||||
return cpuInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeapMemoryInfo getHeapMemoryInfo() {
|
|
||||||
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
|
|
||||||
MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();
|
|
||||||
long initTotalMemorySize = memoryUsage.getInit();
|
|
||||||
long maxMemorySize = memoryUsage.getMax();
|
|
||||||
long usedMemorySize = memoryUsage.getUsed();
|
|
||||||
HeapMemoryInfo heapMemoryInfo = new HeapMemoryInfo();
|
|
||||||
heapMemoryInfo.setInitValue(initTotalMemorySize);
|
|
||||||
heapMemoryInfo.setMaxValue(maxMemorySize);
|
|
||||||
heapMemoryInfo.setUsedValue(usedMemorySize);
|
|
||||||
heapMemoryInfo.setUsedRate(usedMemorySize * 1.0 / maxMemorySize);
|
|
||||||
return heapMemoryInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PhysicalMemoryInfo getPhysicalMemoryInfo() {
|
|
||||||
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
|
|
||||||
PhysicalMemoryInfo physicalMemoryInfo = new PhysicalMemoryInfo();
|
|
||||||
physicalMemoryInfo.setInitValue(osmxb.getTotalPhysicalMemorySize());
|
|
||||||
physicalMemoryInfo.setUsedValue(osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize());
|
|
||||||
physicalMemoryInfo.setFreeValue(osmxb.getFreePhysicalMemorySize());
|
|
||||||
physicalMemoryInfo.setUsedValue(physicalMemoryInfo.getInitValue() - physicalMemoryInfo.getFreeValue());
|
|
||||||
physicalMemoryInfo.setUsedRate(physicalMemoryInfo.getUsedValue() * 1.0 / physicalMemoryInfo.getInitValue());
|
|
||||||
if (isLinux()) {
|
|
||||||
Map<String, String> processInfo = getProcessInfo();
|
|
||||||
if (processInfo.containsKey("VmSize")) {
|
|
||||||
String VmRSSStr = processInfo.get("VmRSS");
|
|
||||||
String VmSizeStr = VmRSSStr.split(" ")[0].trim();
|
|
||||||
long VmRSS = Long.valueOf(VmSizeStr);
|
|
||||||
physicalMemoryInfo.setThisUsedValue(VmRSS*1024);
|
|
||||||
double rate = physicalMemoryInfo.getThisUsedValue()*1.0 / physicalMemoryInfo.getInitValue();
|
|
||||||
physicalMemoryInfo.setThisUsedRate(rate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return physicalMemoryInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLinux() {
|
|
||||||
return System.getProperty("os.name").toLowerCase().contains("linux");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String,String> getProcessInfo() {
|
|
||||||
Map<String,String> processMetrics = new HashMap();
|
|
||||||
Runtime runtime = Runtime.getRuntime();
|
|
||||||
Process process = null;
|
|
||||||
try {
|
|
||||||
process = runtime.exec("cat /proc/" + Context.getPid() + "/status");
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.severe("Can not execute '"+"cat /proc/" + Context.getPid() + "/status"+"'");
|
|
||||||
return processMetrics;
|
|
||||||
}
|
|
||||||
try (InputStream inputStream = process.getInputStream();
|
|
||||||
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
|
|
||||||
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)
|
|
||||||
) {
|
|
||||||
String line ="";
|
|
||||||
while ((line = bufferedReader.readLine()) != null){
|
|
||||||
String[] split = line.split(":");
|
|
||||||
if (split.length==2) {
|
|
||||||
String key = split[0].trim();
|
|
||||||
String value = split[1].trim();
|
|
||||||
processMetrics.put(key,value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.severe("Can not read the result of '"+"cat /proc/" + Context.getPid() + "/status"+"'");
|
|
||||||
}
|
|
||||||
return processMetrics;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package cn.langpy.kotime.service.core;
|
||||||
|
|
||||||
|
|
||||||
|
import com.sun.management.HotSpotDiagnosticMXBean;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.management.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
public class SystemService {
|
||||||
|
Logger log = Logger.getLogger(SystemService.class.toString());
|
||||||
|
private static final String HotSpotDiagnosticName = "com.sun.management:type=HotSpotDiagnostic";
|
||||||
|
|
||||||
|
final static Map<String, SystemService> serviceMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static <T extends SystemService> T getInstance(Class<? extends SystemService> clazz) {
|
||||||
|
String simpleName = clazz.getSimpleName();
|
||||||
|
T systemService = (T) serviceMap.get(simpleName);
|
||||||
|
if (systemService == null) {
|
||||||
|
synchronized (SystemService.class) {
|
||||||
|
if (!serviceMap.containsKey(simpleName)) {
|
||||||
|
try {
|
||||||
|
systemService = (T) clazz.newInstance();
|
||||||
|
serviceMap.put(simpleName, systemService);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
systemService = (T) serviceMap.get(simpleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return systemService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MemoryUsage getHeapMemoryUsage() {
|
||||||
|
return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MemoryUsage getNonHeapMemoryUsage() {
|
||||||
|
return ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {
|
||||||
|
return ManagementFactory.getGarbageCollectorMXBeans();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
|
||||||
|
return ManagementFactory.getMemoryPoolMXBeans();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ThreadMXBean getThreadMXBean() {
|
||||||
|
return ManagementFactory.getThreadMXBean();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ClassLoadingMXBean getClassLoadingMXBean() {
|
||||||
|
return ManagementFactory.getClassLoadingMXBean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HotSpotDiagnosticMXBean getHotSpotDiagnosticMXBean() {
|
||||||
|
HotSpotDiagnosticMXBean hotSpotDiagnostic = null;
|
||||||
|
try {
|
||||||
|
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||||
|
hotSpotDiagnostic = ManagementFactory.newPlatformMXBeanProxy(server, HotSpotDiagnosticName, HotSpotDiagnosticMXBean.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return hotSpotDiagnostic;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
package cn.langpy.kotime.service;
|
package cn.langpy.kotime.service.metric;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.model.ClassUsage;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
import cn.langpy.kotime.util.Context;
|
import cn.langpy.kotime.util.Context;
|
||||||
import net.bytebuddy.agent.VirtualMachine;
|
import net.bytebuddy.agent.VirtualMachine;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
@ -8,20 +10,28 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.management.ClassLoadingMXBean;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarOutputStream;
|
import java.util.jar.JarOutputStream;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class JvmAttachClassService implements ClassService{
|
public class ClassInfoService extends SystemService {
|
||||||
private static Logger log = Logger.getLogger(JvmAttachClassService.class.toString());
|
Logger log = Logger.getLogger(ClassInfoService.class.toString());
|
||||||
|
|
||||||
|
public ClassUsage getClassUsage() {
|
||||||
|
ClassUsage usage = new ClassUsage();
|
||||||
|
ClassLoadingMXBean classLoadingMXBean = getClassLoadingMXBean();
|
||||||
|
usage.setTotalClassNum(classLoadingMXBean.getTotalLoadedClassCount());
|
||||||
|
usage.setCurrentClassNum(classLoadingMXBean.getLoadedClassCount());
|
||||||
|
usage.setUnloadedClassNum(classLoadingMXBean.getUnloadedClassCount());
|
||||||
|
return usage;
|
||||||
|
}
|
||||||
private File agentJar;
|
private File agentJar;
|
||||||
|
|
||||||
public JvmAttachClassService() {
|
public ClassInfoService() {
|
||||||
this.agentJar = createAgentJar();
|
this.agentJar = createAgentJar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateClass(String className, String classPath) {
|
public void updateClass(String className, String classPath) {
|
||||||
try {
|
try {
|
||||||
if (agentJar==null || !agentJar.exists()) {
|
if (agentJar==null || !agentJar.exists()) {
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package cn.langpy.kotime.service.metric;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.model.CpuUsage;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
import oshi.SystemInfo;
|
||||||
|
import oshi.hardware.CentralProcessor;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class CpuMetricService extends SystemService {
|
||||||
|
Logger log = Logger.getLogger(CpuMetricService.class.toString());
|
||||||
|
public CpuUsage getCpuUsage() {
|
||||||
|
SystemInfo systemInfo = new SystemInfo();
|
||||||
|
CentralProcessor processor = systemInfo.getHardware().getProcessor();
|
||||||
|
long[] prevTicks = processor.getSystemCpuLoadTicks();
|
||||||
|
try {
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
long[] ticks = processor.getSystemCpuLoadTicks();
|
||||||
|
long nice = ticks[CentralProcessor.TickType.NICE.getIndex()]
|
||||||
|
- prevTicks[CentralProcessor.TickType.NICE.getIndex()];
|
||||||
|
|
||||||
|
long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()]
|
||||||
|
- prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
|
||||||
|
|
||||||
|
long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()]
|
||||||
|
- prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
|
||||||
|
|
||||||
|
long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()]
|
||||||
|
- prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
|
||||||
|
|
||||||
|
long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()]
|
||||||
|
- prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
|
||||||
|
|
||||||
|
long user = ticks[CentralProcessor.TickType.USER.getIndex()]
|
||||||
|
- prevTicks[CentralProcessor.TickType.USER.getIndex()];
|
||||||
|
|
||||||
|
long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()]
|
||||||
|
- prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
|
||||||
|
|
||||||
|
long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()]
|
||||||
|
- prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
|
||||||
|
|
||||||
|
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
|
||||||
|
CpuUsage cpuInfo = new CpuUsage();
|
||||||
|
cpuInfo.setLogicalNum(processor.getLogicalProcessorCount());
|
||||||
|
cpuInfo.setUserRate(user * 1.0 / totalCpu);
|
||||||
|
cpuInfo.setSysRate(cSys * 1.0 / totalCpu);
|
||||||
|
cpuInfo.setWaitRate(iowait * 1.0 / totalCpu);
|
||||||
|
cpuInfo.setSystemLoad(processor.getSystemCpuLoad(1000));
|
||||||
|
return cpuInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package cn.langpy.kotime.service.metric;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.model.GcUsage;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
|
||||||
|
import java.lang.management.GarbageCollectorMXBean;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class GcMetricService extends SystemService {
|
||||||
|
private final static List<String> youngMemoryPool = Arrays.asList("PS Eden Space", "PS Survivor Space");
|
||||||
|
private final static List<String> oldMemoryPool = Arrays.asList("PS Old Gen", "Metaspace");
|
||||||
|
Logger log = Logger.getLogger(GcMetricService.class.toString());
|
||||||
|
|
||||||
|
public GcUsage getGcUsage() {
|
||||||
|
GcUsage gcUsage = new GcUsage();
|
||||||
|
gcUsage.setFullNum(0L);
|
||||||
|
gcUsage.setMinorNum(0L);
|
||||||
|
gcUsage.setFullCostTime(0L);
|
||||||
|
gcUsage.setMinorCostTime(0L);
|
||||||
|
List<GarbageCollectorMXBean> garbageCollectorMXBeans = getGarbageCollectorMXBeans();
|
||||||
|
for (GarbageCollectorMXBean bean : garbageCollectorMXBeans) {
|
||||||
|
if (isFullGc(bean)) {
|
||||||
|
gcUsage.setFullNum(gcUsage.getFullNum() + bean.getCollectionCount());
|
||||||
|
gcUsage.setFullCostTime(gcUsage.getFullCostTime() + bean.getCollectionTime());
|
||||||
|
} else if (isMinorGc(bean)) {
|
||||||
|
gcUsage.setMinorNum(gcUsage.getMinorNum() + bean.getCollectionCount());
|
||||||
|
gcUsage.setMinorCostTime(gcUsage.getMinorCostTime() + bean.getCollectionTime());
|
||||||
|
} else {
|
||||||
|
log.warning("kotime=>Can not recognize the garbage collector: " + bean);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gcUsage.setTotalNum(gcUsage.getFullNum() + gcUsage.getMinorNum());
|
||||||
|
return gcUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMinorGc(GarbageCollectorMXBean bean) {
|
||||||
|
String[] memoryPoolNames = bean.getMemoryPoolNames();
|
||||||
|
boolean isMinor = false;
|
||||||
|
boolean isMajor = false;
|
||||||
|
for (String memoryPoolName : memoryPoolNames) {
|
||||||
|
if (youngMemoryPool.contains(memoryPoolName)) {
|
||||||
|
isMinor = true;
|
||||||
|
}
|
||||||
|
if (oldMemoryPool.contains(memoryPoolName)) {
|
||||||
|
isMajor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isMinor && !isMajor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFullGc(GarbageCollectorMXBean bean) {
|
||||||
|
String[] memoryPoolNames = bean.getMemoryPoolNames();
|
||||||
|
boolean isMajor = false;
|
||||||
|
for (String memoryPoolName : memoryPoolNames) {
|
||||||
|
if (oldMemoryPool.contains(memoryPoolName)) {
|
||||||
|
isMajor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isMajor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package cn.langpy.kotime.service.metric;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.model.JvmMemoryInfo;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.management.MemoryPoolMXBean;
|
||||||
|
import java.lang.management.MemoryUsage;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
public class JvmSpaceMetricService extends SystemService {
|
||||||
|
Logger log = Logger.getLogger(JvmSpaceMetricService.class.toString());
|
||||||
|
|
||||||
|
public JvmMemoryInfo getEdenSpaceInfo() {
|
||||||
|
return getSpaceInfo("PS Eden Space");
|
||||||
|
}
|
||||||
|
|
||||||
|
public JvmMemoryInfo getSurvivorSpaceInfo() {
|
||||||
|
return getSpaceInfo("PS Survivor Space");
|
||||||
|
}
|
||||||
|
|
||||||
|
public JvmMemoryInfo getOldGenInfo() {
|
||||||
|
return getSpaceInfo("PS Old Gen");
|
||||||
|
}
|
||||||
|
|
||||||
|
public JvmMemoryInfo getMetaspaceInfo() {
|
||||||
|
return getSpaceInfo("Metaspace");
|
||||||
|
}
|
||||||
|
|
||||||
|
private JvmMemoryInfo getSpaceInfo(String name) {
|
||||||
|
List<MemoryPoolMXBean> memoryPoolMXBeans = getMemoryPoolMXBeans();
|
||||||
|
Map<String, MemoryPoolMXBean> mxBeanMap = memoryPoolMXBeans.stream().collect(Collectors.toMap(v -> v.getName(), v -> v));
|
||||||
|
MemoryPoolMXBean psEdenSpace = mxBeanMap.get(name);
|
||||||
|
JvmMemoryInfo heapMemoryInfo = new JvmMemoryInfo();
|
||||||
|
if (psEdenSpace == null) {
|
||||||
|
heapMemoryInfo.setInitValue(0L);
|
||||||
|
heapMemoryInfo.setMaxValue(0L);
|
||||||
|
heapMemoryInfo.setUsedValue(0L);
|
||||||
|
heapMemoryInfo.setUsedRate(0.0);
|
||||||
|
return heapMemoryInfo;
|
||||||
|
}
|
||||||
|
MemoryUsage usage = psEdenSpace.getUsage();
|
||||||
|
heapMemoryInfo.setInitValue(usage.getInit());
|
||||||
|
heapMemoryInfo.setMaxValue(usage.getMax());
|
||||||
|
heapMemoryInfo.setUsedValue(usage.getUsed());
|
||||||
|
heapMemoryInfo.setUsedRate(usage.getUsed() * 1.0 / usage.getMax());
|
||||||
|
return heapMemoryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,127 @@
|
|||||||
|
package cn.langpy.kotime.service.metric;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.model.JvmMemoryInfo;
|
||||||
|
import cn.langpy.kotime.model.PhysicalMemoryInfo;
|
||||||
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
import cn.langpy.kotime.util.Context;
|
||||||
|
import com.sun.management.HotSpotDiagnosticMXBean;
|
||||||
|
import com.sun.management.OperatingSystemMXBean;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.MemoryUsage;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class MemoryMetricService extends SystemService {
|
||||||
|
Logger log = Logger.getLogger(MemoryMetricService.class.toString());
|
||||||
|
private static final String STANDARD_DUMP_NAME = "kotime-heapdump-%s.hprof";
|
||||||
|
|
||||||
|
public JvmMemoryInfo getHeapMemoryInfo() {
|
||||||
|
MemoryUsage memoryUsage = getHeapMemoryUsage();
|
||||||
|
long initTotalMemorySize = memoryUsage.getInit();
|
||||||
|
long maxMemorySize = memoryUsage.getMax();
|
||||||
|
long usedMemorySize = memoryUsage.getUsed();
|
||||||
|
JvmMemoryInfo heapMemoryInfo = new JvmMemoryInfo();
|
||||||
|
heapMemoryInfo.setInitValue(initTotalMemorySize);
|
||||||
|
heapMemoryInfo.setMaxValue(maxMemorySize);
|
||||||
|
heapMemoryInfo.setUsedValue(usedMemorySize);
|
||||||
|
heapMemoryInfo.setUsedRate(usedMemorySize * 1.0 / maxMemorySize);
|
||||||
|
return heapMemoryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JvmMemoryInfo getNonHeapMemoryInfo() {
|
||||||
|
MemoryUsage memoryUsage = getNonHeapMemoryUsage();
|
||||||
|
long initTotalMemorySize = memoryUsage.getInit();
|
||||||
|
long maxMemorySize = memoryUsage.getMax();
|
||||||
|
long usedMemorySize = memoryUsage.getUsed();
|
||||||
|
JvmMemoryInfo heapMemoryInfo = new JvmMemoryInfo();
|
||||||
|
heapMemoryInfo.setInitValue(initTotalMemorySize);
|
||||||
|
heapMemoryInfo.setMaxValue(maxMemorySize);
|
||||||
|
heapMemoryInfo.setUsedValue(usedMemorySize);
|
||||||
|
heapMemoryInfo.setUsedRate(usedMemorySize * 1.0 / maxMemorySize);
|
||||||
|
return heapMemoryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhysicalMemoryInfo getPhysicalMemoryInfo() {
|
||||||
|
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
|
||||||
|
PhysicalMemoryInfo physicalMemoryInfo = new PhysicalMemoryInfo();
|
||||||
|
physicalMemoryInfo.setInitValue(osmxb.getTotalPhysicalMemorySize());
|
||||||
|
physicalMemoryInfo.setUsedValue(osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize());
|
||||||
|
physicalMemoryInfo.setFreeValue(osmxb.getFreePhysicalMemorySize());
|
||||||
|
physicalMemoryInfo.setUsedValue(physicalMemoryInfo.getInitValue() - physicalMemoryInfo.getFreeValue());
|
||||||
|
physicalMemoryInfo.setUsedRate(physicalMemoryInfo.getUsedValue() * 1.0 / physicalMemoryInfo.getInitValue());
|
||||||
|
if (isLinux()) {
|
||||||
|
Map<String, String> processInfo = getProcessInfo();
|
||||||
|
if (processInfo.containsKey("VmSize")) {
|
||||||
|
String VmRSSStr = processInfo.get("VmRSS");
|
||||||
|
String VmSizeStr = VmRSSStr.split(" ")[0].trim();
|
||||||
|
long VmRSS = Long.valueOf(VmSizeStr);
|
||||||
|
physicalMemoryInfo.setThisUsedValue(VmRSS * 1024);
|
||||||
|
double rate = physicalMemoryInfo.getThisUsedValue() * 1.0 / physicalMemoryInfo.getInitValue();
|
||||||
|
physicalMemoryInfo.setThisUsedRate(rate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return physicalMemoryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLinux() {
|
||||||
|
return System.getProperty("os.name").toLowerCase().contains("linux");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getProcessInfo() {
|
||||||
|
Map<String, String> processMetrics = new HashMap();
|
||||||
|
Runtime runtime = Runtime.getRuntime();
|
||||||
|
Process process = null;
|
||||||
|
try {
|
||||||
|
process = runtime.exec("cat /proc/" + Context.getPid() + "/status");
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.severe("Can not execute '" + "cat /proc/" + Context.getPid() + "/status" + "'");
|
||||||
|
return processMetrics;
|
||||||
|
}
|
||||||
|
try (InputStream inputStream = process.getInputStream();
|
||||||
|
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
|
||||||
|
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)
|
||||||
|
) {
|
||||||
|
String line = "";
|
||||||
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
String[] split = line.split(":");
|
||||||
|
if (split.length == 2) {
|
||||||
|
String key = split[0].trim();
|
||||||
|
String value = split[1].trim();
|
||||||
|
processMetrics.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.severe("Can not read the result of '" + "cat /proc/" + Context.getPid() + "/status" + "'");
|
||||||
|
}
|
||||||
|
return processMetrics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeapDumpFile(boolean live) {
|
||||||
|
String targetFile = System.getProperty("java.io.tmpdir") + File.separator + getHeapDumpFileName(live);
|
||||||
|
try {
|
||||||
|
HotSpotDiagnosticMXBean hotSpotDiagnostic = getHotSpotDiagnosticMXBean();
|
||||||
|
if (Files.exists(Paths.get(targetFile))) {
|
||||||
|
new File(targetFile).delete();
|
||||||
|
}
|
||||||
|
hotSpotDiagnostic.dumpHeap(targetFile, live);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.severe("Can not dump heap file!");
|
||||||
|
}
|
||||||
|
return targetFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeapDumpFileName(boolean live) {
|
||||||
|
if (live) {
|
||||||
|
return String.format(STANDARD_DUMP_NAME, "live");
|
||||||
|
}
|
||||||
|
return String.format(STANDARD_DUMP_NAME, "all");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,10 +1,9 @@
|
|||||||
package cn.langpy.kotime.service;
|
package cn.langpy.kotime.service.metric;
|
||||||
|
|
||||||
import cn.langpy.kotime.model.ThreadInfo;
|
import cn.langpy.kotime.model.ThreadInfo;
|
||||||
import cn.langpy.kotime.util.Context;
|
import cn.langpy.kotime.model.ThreadUsage;
|
||||||
import org.springframework.util.CollectionUtils;
|
import cn.langpy.kotime.service.core.SystemService;
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.lang.management.ThreadMXBean;
|
import java.lang.management.ThreadMXBean;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -15,19 +14,38 @@ import java.util.List;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ThreadUsageService {
|
public class ThreadMetricService extends SystemService {
|
||||||
private static Logger log = Logger.getLogger(ThreadUsageService.class.toString());
|
private static Logger log = Logger.getLogger(ThreadMetricService.class.toString());
|
||||||
|
|
||||||
public static ThreadUsageService newInstance() {
|
|
||||||
return new ThreadUsageService();
|
public ThreadUsage getThreadUsage() {
|
||||||
|
ThreadUsage usage = new ThreadUsage();
|
||||||
|
List<ThreadInfo> threads = getThreads();
|
||||||
|
usage.setTotalNum(threads.size());
|
||||||
|
usage.setRunnableNum(getThreads("RUNNABLE").size());
|
||||||
|
long[] deadlockedThreads = getThreadMXBean().findDeadlockedThreads();
|
||||||
|
usage.setDeadLockNum(deadlockedThreads==null?0:deadlockedThreads.length);
|
||||||
|
return usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Long> getDeadlockThreadIds() {
|
||||||
|
List<Long> threads = new ArrayList<>();
|
||||||
|
long[] deadlockedThreads = getThreadMXBean().findDeadlockedThreads();
|
||||||
|
if (deadlockedThreads==null || deadlockedThreads.length == 0) {
|
||||||
|
return threads;
|
||||||
|
}
|
||||||
|
java.lang.management.ThreadInfo[] threadInfos = getThreadMXBean().getThreadInfo(deadlockedThreads);
|
||||||
|
List<Long> collect = Arrays.stream(threadInfos).map(a -> a.getThreadId()).collect(Collectors.toList());
|
||||||
|
return collect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ThreadInfo> getThreads() {
|
public List<ThreadInfo> getThreads() {
|
||||||
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
|
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
|
||||||
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();;
|
ThreadMXBean threadMXBean = getThreadMXBean();
|
||||||
int activeCount = threadGroup.activeCount();
|
int activeCount = threadGroup.activeCount();
|
||||||
Thread[] threads = new Thread[activeCount];
|
Thread[] threads = new Thread[activeCount];
|
||||||
threadGroup.enumerate(threads);
|
threadGroup.enumerate(threads);
|
||||||
|
List<Long> deadlockThreadIds = getDeadlockThreadIds();
|
||||||
List<ThreadInfo> list = new ArrayList<>();
|
List<ThreadInfo> list = new ArrayList<>();
|
||||||
for (int i = 0; i < activeCount; i++) {
|
for (int i = 0; i < activeCount; i++) {
|
||||||
Thread thread = threads[i];
|
Thread thread = threads[i];
|
||||||
@ -48,6 +66,11 @@ public class ThreadUsageService {
|
|||||||
threadInfo.setPriority(thread.getPriority());
|
threadInfo.setPriority(thread.getPriority());
|
||||||
StackTraceElement[] stackTrace = thread.getStackTrace();
|
StackTraceElement[] stackTrace = thread.getStackTrace();
|
||||||
threadInfo.setStacks(Arrays.stream(stackTrace).collect(Collectors.toList()));
|
threadInfo.setStacks(Arrays.stream(stackTrace).collect(Collectors.toList()));
|
||||||
|
if (deadlockThreadIds.contains(thread.getId())) {
|
||||||
|
threadInfo.setDeadLock(true);
|
||||||
|
}else {
|
||||||
|
threadInfo.setDeadLock(false);
|
||||||
|
}
|
||||||
list.add(threadInfo);
|
list.add(threadInfo);
|
||||||
}
|
}
|
||||||
Collections.sort(list, Comparator.comparing(ThreadInfo::getCpuUsage).reversed());
|
Collections.sort(list, Comparator.comparing(ThreadInfo::getCpuUsage).reversed());
|
||||||
@ -1 +1 @@
|
|||||||
ko-time.version=3.0.2
|
ko-time.version=3.1.0
|
||||||
@ -15,3 +15,55 @@
|
|||||||
font-weight: 430;
|
font-weight: 430;
|
||||||
color: #3621a5;
|
color: #3621a5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.metric-card {
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #fefffe;
|
||||||
|
padding: 10px 20px 15px 20px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card-summary-n {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #1f2541;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card-summary-v {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #020718;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card-item {
|
||||||
|
text-align: left;
|
||||||
|
margin-top: -13px;
|
||||||
|
/*margin-left: -40px;*/
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card-item li {
|
||||||
|
line-height: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.metric-card-item-n {
|
||||||
|
font-size: 8px;
|
||||||
|
color: #3b3f4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card-item-v {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #020718;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card-item-point {
|
||||||
|
width: 4px;
|
||||||
|
height: 4px;
|
||||||
|
background-color: #11de71;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-bottom:1px;
|
||||||
|
}
|
||||||
@ -10,8 +10,9 @@ tab.configuration=配置
|
|||||||
tab.support=技术支持
|
tab.support=技术支持
|
||||||
|
|
||||||
tab.summary.interface-metric=接口统计
|
tab.summary.interface-metric=接口统计
|
||||||
tab.summary.response-metric=响应统计
|
tab.summary.memory-metric=内存统计
|
||||||
tab.summary.sysusage-metric=系统使用情况
|
tab.summary.jvm-metric=JVM空间统计
|
||||||
|
tab.summary.other-metric=其他指标
|
||||||
tab.summary.bottom-normal-tip=接口根据调用情况统计,未调用的接口无法被统计到,请先调用接口
|
tab.summary.bottom-normal-tip=接口根据调用情况统计,未调用的接口无法被统计到,请先调用接口
|
||||||
tab.summary.bottom-close-tip=方法调用监测已关闭,数据将不会更新,需要开启请到配置面板
|
tab.summary.bottom-close-tip=方法调用监测已关闭,数据将不会更新,需要开启请到配置面板
|
||||||
|
|
||||||
@ -23,9 +24,21 @@ tab.summary.response-metric.avg-num=平均响应(ms)
|
|||||||
tab.summary.response-metric.max-num=最大响应(ms)
|
tab.summary.response-metric.max-num=最大响应(ms)
|
||||||
tab.summary.response-metric.min-num=最小响应(ms)
|
tab.summary.response-metric.min-num=最小响应(ms)
|
||||||
|
|
||||||
tab.summary.sysusage-metric.cpu-usage=CPU使用率
|
tab.summary.interface-metric.avg-call-num=平均调用数
|
||||||
|
tab.summary.interface-metric.max-call-num=最大调用数
|
||||||
|
tab.summary.interface-metric.min-call-num=最小调用数
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.cpu-usage=CPU
|
||||||
tab.summary.sysusage-metric.heap-memory=堆内存
|
tab.summary.sysusage-metric.heap-memory=堆内存
|
||||||
|
tab.summary.sysusage-metric.non-heap-memory=非堆内存
|
||||||
tab.summary.sysusage-metric.physical-memory=物理内存
|
tab.summary.sysusage-metric.physical-memory=物理内存
|
||||||
|
tab.summary.sysusage-metric.eden-space=Eden
|
||||||
|
tab.summary.sysusage-metric.survivor-space=Survivor
|
||||||
|
tab.summary.sysusage-metric.old-gen=OldGen
|
||||||
|
tab.summary.sysusage-metric.meta-space=Metaspace
|
||||||
|
tab.summary.sysusage-metric.gc-num=GC次数
|
||||||
|
tab.summary.sysusage-metric.thread-num=线程数
|
||||||
|
tab.summary.sysusage-metric.loaded-class-num=加载类总数
|
||||||
|
|
||||||
tab.summary.sysusage-metric.cpu-usage.user-usage=用户使用率
|
tab.summary.sysusage-metric.cpu-usage.user-usage=用户使用率
|
||||||
tab.summary.sysusage-metric.cpu-usage.sys-usage=系统使用率
|
tab.summary.sysusage-metric.cpu-usage.sys-usage=系统使用率
|
||||||
@ -39,6 +52,14 @@ tab.summary.sysusage-metric.physical-memory.total=总物理内存
|
|||||||
tab.summary.sysusage-metric.physical-memory.used=已使用内存
|
tab.summary.sysusage-metric.physical-memory.used=已使用内存
|
||||||
tab.summary.sysusage-metric.physical-memory.current-used=此程序占用
|
tab.summary.sysusage-metric.physical-memory.current-used=此程序占用
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.gc-num.minor=Minor GC
|
||||||
|
tab.summary.sysusage-metric.gc-num.full=Major/Full GC
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.thread-num.runnable=运行数
|
||||||
|
tab.summary.sysusage-metric.thread-num.deadlock=死锁数
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.loaded-class-num.current=当前类总数
|
||||||
|
tab.summary.sysusage-metric.loaded-class-num.unloaded=卸载类数
|
||||||
|
|
||||||
tab.interface.search-tip=搜索方法名或者类名...
|
tab.interface.search-tip=搜索方法名或者类名...
|
||||||
tab.interface.interface-list.avg-tip=平均响应
|
tab.interface.interface-list.avg-tip=平均响应
|
||||||
|
|||||||
@ -9,9 +9,10 @@ tab.hotupdate=Hot Update
|
|||||||
tab.configuration=Configurations
|
tab.configuration=Configurations
|
||||||
tab.support=Tech Support
|
tab.support=Tech Support
|
||||||
|
|
||||||
tab.summary.interface-metric=Number of Interface
|
tab.summary.interface-metric=Interface Indices
|
||||||
tab.summary.response-metric=Response Time
|
tab.summary.memory-metric=Memory Indices
|
||||||
tab.summary.sysusage-metric=System Usage
|
tab.summary.jvm-metric=JVM Indices
|
||||||
|
tab.summary.other-metric=Other Indices
|
||||||
tab.summary.bottom-normal-tip=Please call apis before visiting this page!
|
tab.summary.bottom-normal-tip=Please call apis before visiting this page!
|
||||||
tab.summary.bottom-close-tip=KoTime switch was closed!
|
tab.summary.bottom-close-tip=KoTime switch was closed!
|
||||||
|
|
||||||
@ -23,9 +24,21 @@ tab.summary.response-metric.avg-num=Avg(ms)
|
|||||||
tab.summary.response-metric.max-num=Max(ms)
|
tab.summary.response-metric.max-num=Max(ms)
|
||||||
tab.summary.response-metric.min-num=Min(ms)
|
tab.summary.response-metric.min-num=Min(ms)
|
||||||
|
|
||||||
tab.summary.sysusage-metric.cpu-usage=CPU Usage
|
tab.summary.interface-metric.avg-call-num=Avg Call-Number
|
||||||
|
tab.summary.interface-metric.max-call-num=Max Call-Number
|
||||||
|
tab.summary.interface-metric.min-call-num=Min Call-Number
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.cpu-usage=CPU
|
||||||
tab.summary.sysusage-metric.heap-memory=Heap Memory
|
tab.summary.sysusage-metric.heap-memory=Heap Memory
|
||||||
|
tab.summary.sysusage-metric.non-heap-memory=Non-Heap Memory
|
||||||
tab.summary.sysusage-metric.physical-memory=Physical Memory
|
tab.summary.sysusage-metric.physical-memory=Physical Memory
|
||||||
|
tab.summary.sysusage-metric.eden-space=Eden
|
||||||
|
tab.summary.sysusage-metric.survivor-space=Survivor
|
||||||
|
tab.summary.sysusage-metric.old-gen=OldGen
|
||||||
|
tab.summary.sysusage-metric.meta-space=Metaspace
|
||||||
|
tab.summary.sysusage-metric.gc-num=GC
|
||||||
|
tab.summary.sysusage-metric.thread-num=Thread Number
|
||||||
|
tab.summary.sysusage-metric.loaded-class-num=Loaded Class
|
||||||
|
|
||||||
tab.summary.sysusage-metric.cpu-usage.user-usage=User Usage
|
tab.summary.sysusage-metric.cpu-usage.user-usage=User Usage
|
||||||
tab.summary.sysusage-metric.cpu-usage.sys-usage=System Usage
|
tab.summary.sysusage-metric.cpu-usage.sys-usage=System Usage
|
||||||
@ -39,6 +52,14 @@ tab.summary.sysusage-metric.physical-memory.total=Total
|
|||||||
tab.summary.sysusage-metric.physical-memory.used=Used
|
tab.summary.sysusage-metric.physical-memory.used=Used
|
||||||
tab.summary.sysusage-metric.physical-memory.current-used=ThisUsed
|
tab.summary.sysusage-metric.physical-memory.current-used=ThisUsed
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.gc-num.minor=Minor GC
|
||||||
|
tab.summary.sysusage-metric.gc-num.full=Major/Full GC
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.thread-num.runnable=Runnable
|
||||||
|
tab.summary.sysusage-metric.thread-num.deadlock=Deadlock
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.loaded-class-num.current=Current
|
||||||
|
tab.summary.sysusage-metric.loaded-class-num.unloaded=Unloaded
|
||||||
|
|
||||||
tab.interface.search-tip=search method name or class name...
|
tab.interface.search-tip=search method name or class name...
|
||||||
tab.interface.interface-list.avg-tip=avg
|
tab.interface.interface-list.avg-tip=avg
|
||||||
|
|||||||
@ -1,343 +0,0 @@
|
|||||||
function checkLogin() {
|
|
||||||
$.get(contextPath+'/koTime/isLogin?kotoken=' + globalToken+"&project="+globalProject, function (data) {
|
|
||||||
globalIsLogin = data['isLogin'] == 1 ? true : false;
|
|
||||||
});
|
|
||||||
if (globalNeedLogin == true && globalIsLogin == false) {
|
|
||||||
UIkit.modal(document.getElementById("modal-login")).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadConfig(){
|
|
||||||
$.get(contextPath+'/koTime/getConfig?kotoken='+globalToken+"&project="+globalProject, function (data) {
|
|
||||||
// let exceptionEnable = data['exceptionEnable'];
|
|
||||||
//
|
|
||||||
// let exceptionEnableDom = document.getElementById('exceptionEnable');
|
|
||||||
// exceptionEnableDom.checked = exceptionEnable;
|
|
||||||
//
|
|
||||||
|
|
||||||
let kotimeEnable = data['enable'];
|
|
||||||
// let kotimeEnableDom = document.getElementById('kotimeEnable');
|
|
||||||
// kotimeEnableDom.checked = kotimeEnable;
|
|
||||||
|
|
||||||
let apiTip = document.getElementById('apiTip');
|
|
||||||
apiTip.innerHTML = kotimeEnable==true?"接口根据调用情况统计,未调用的接口无法被统计到,请先调用接口":"方法调用监测已关闭,数据将不会更新,需要开启请到配置面板";
|
|
||||||
|
|
||||||
let threshold = data['threshold'];
|
|
||||||
let timeThresholdDom = document.getElementById('timeThreshold');
|
|
||||||
timeThresholdDom.value = threshold;
|
|
||||||
|
|
||||||
// let logEnable = data['logEnable'];
|
|
||||||
// let logEnableDom = document.getElementById('logEnable');
|
|
||||||
// logEnableDom.checked = logEnable;
|
|
||||||
|
|
||||||
let language = data['language'];
|
|
||||||
$("#languageSwitch").val(language)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addConfigEvent(){
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementById('languageSwitch').onchange = function(){
|
|
||||||
let selectedObj = document.getElementById('languageSwitch');
|
|
||||||
$.ajax({type:'POST',url:contextPath+'/koTime/updateConfig?kotoken='+globalToken+"&project="+globalProject,data:JSON.stringify({language:selectedObj.options[selectedObj.selectedIndex].value}),dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
};
|
|
||||||
|
|
||||||
document.getElementById("timeThresholdYes").onclick = function(){
|
|
||||||
$.ajax({type:'POST',url:contextPath+'/koTime/updateConfig?kotoken='+globalToken+"&project="+globalProject,data:JSON.stringify({threshold:document.getElementById('timeThreshold').value}),dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadStatistic(){
|
|
||||||
$.get(contextPath+'/koTime/getStatistic?kotoken='+globalToken+"&project="+globalProject, function (data) {
|
|
||||||
let totalNum = data['totalNum'];
|
|
||||||
let systemTotalNum = document.getElementById("systemTotalNum");
|
|
||||||
systemTotalNum.innerHTML=totalNum;
|
|
||||||
|
|
||||||
let normalNum = data['normalNum'];
|
|
||||||
let systemNormalNum = document.getElementById("systemNormalNum");
|
|
||||||
systemNormalNum.innerHTML=normalNum;
|
|
||||||
|
|
||||||
let delayNum = data['delayNum'];
|
|
||||||
let systemDelayNum = document.getElementById("systemDelayNum");
|
|
||||||
systemDelayNum.innerHTML=delayNum;
|
|
||||||
if (delayNum>0) {
|
|
||||||
document.getElementById("systemDelayNum-div").className+=' uk-label-danger';
|
|
||||||
}else {
|
|
||||||
document.getElementById("systemDelayNum-div").className+=' uk-label-success';
|
|
||||||
};
|
|
||||||
|
|
||||||
let avgRunTime = data['avgRunTime'];
|
|
||||||
let systemAvgRunTime = document.getElementById("systemAvgRunTime");
|
|
||||||
systemAvgRunTime.innerHTML=avgRunTime;
|
|
||||||
if (avgRunTime>globalThreshold) {
|
|
||||||
document.getElementById("systemAvgRunTime-div").className+=' uk-label-danger';
|
|
||||||
}else {
|
|
||||||
document.getElementById("systemAvgRunTime-div").className+=' uk-label-success';
|
|
||||||
};
|
|
||||||
|
|
||||||
let maxRunTime = data['maxRunTime'];
|
|
||||||
let systemMaxRunTime = document.getElementById("systemMaxRunTime");
|
|
||||||
systemMaxRunTime.innerHTML=maxRunTime;
|
|
||||||
if (maxRunTime>globalThreshold) {
|
|
||||||
document.getElementById("systemMaxRunTime-div").className+=' uk-label-danger';
|
|
||||||
}else {
|
|
||||||
document.getElementById("systemMaxRunTime-div").className+=' uk-label-success';
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
let minRunTime = data['minRunTime'];
|
|
||||||
let systemMinRunTime = document.getElementById("systemMinRunTime");
|
|
||||||
systemMinRunTime.innerHTML=minRunTime;
|
|
||||||
if (minRunTime>globalThreshold) {
|
|
||||||
document.getElementById("systemMinRunTime-div").className+=' uk-label-danger';
|
|
||||||
}else {
|
|
||||||
document.getElementById("systemMinRunTime-div").className+=' uk-label-success';
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadApis(){
|
|
||||||
let searchText = $("#searchText").val();
|
|
||||||
$.get(contextPath+'/koTime/getApis?question='+searchText+'&kotoken='+globalToken+"&project="+globalProject, function (data) {
|
|
||||||
let element = document.getElementById('apiList');
|
|
||||||
html = '';
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
let id = data[i]['id'];
|
|
||||||
let className = data[i]['className'];
|
|
||||||
let methodName = data[i]['methodName'];
|
|
||||||
let avgRunTime = data[i]['avgRunTime'];
|
|
||||||
let methodType = data[i]['methodType'];
|
|
||||||
let routeName = data[i]['routeName'];
|
|
||||||
|
|
||||||
let apiId = className+"."+methodName;
|
|
||||||
let color = avgRunTime>globalThreshold?'danger':'success';
|
|
||||||
if (methodType=='Controller' && routeName!=null && routeName!='') {
|
|
||||||
html += "<li onclick=\"showMethods('"+id+"')\" style='color: #333;font-weight: 400;font-size: 14px;' id=\""+apiId+"-list\">"+ className+"#<span style='font-size: 16px;font-weight: 500;'>"+methodName+"</span> (<span style='font-size: 14px;font-weight: 430;color:#032b11'>"+routeName+"</span>)   <span style='font-size: 10px;' class=\"uk-label uk-label-"+color+"\">avg "+avgRunTime+" ms</span></li>";
|
|
||||||
}else{
|
|
||||||
html += "<li onclick=\"showMethods('"+id+"')\" style='color: #333;font-weight: 400;font-size: 14px;' id=\""+apiId+"-list\">"+ className+"#<span style='font-size: 16px;font-weight: 500;'>"+methodName+"</span>   <span style='font-size: 10px;' class=\"uk-label uk-label-"+color+"\">avg "+avgRunTime+" ms</span></li>";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
element.innerHTML = html;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadExceptions(){
|
|
||||||
$.get(contextPath+'/koTime/getExceptions?kotoken='+globalToken+"&project="+globalProject, function (data) {
|
|
||||||
let element = document.getElementById('exceptionList');
|
|
||||||
html = '';
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
let id = data[i]['id'];
|
|
||||||
let className = data[i]['className'];
|
|
||||||
let message = data[i]['message'];
|
|
||||||
html += "<li onclick=\"showExceptions('"+id+"','"+message+"')\" style='' id=\""+id+"\"><span style='font-size: 16px;font-weight: 500;'>"+className+"</span>   <span style='font-size: 10px;' class=\"uk-label uk-label-danger\">"+message+"</span></li>";
|
|
||||||
};
|
|
||||||
element.innerHTML = html;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let methodParamMap = new Map();
|
|
||||||
function paramGraph(e) {
|
|
||||||
let clickNode = e.currentTarget;
|
|
||||||
if (clickNode==null){
|
|
||||||
return
|
|
||||||
};
|
|
||||||
let clickNodeId = clickNode.id;
|
|
||||||
if (methodParamMap.has(clickNodeId+"ana")) {
|
|
||||||
graph.removeNode(clickNodeId+"ana")
|
|
||||||
methodParamMap.delete(clickNodeId+"ana")
|
|
||||||
}else {
|
|
||||||
$.get(contextPath+'/koTime/getParamGraph?kotoken='+globalToken+"&methodId="+clickNodeId.replace('node','')+"&project="+globalProject, function (data) {
|
|
||||||
let datas = []
|
|
||||||
for(let key in data) {
|
|
||||||
datas.push( {"name":key+":avg "+data[key]['avgRunTime']+" ms"})
|
|
||||||
};
|
|
||||||
let paramGraphData = {
|
|
||||||
"id":clickNodeId+"ana",
|
|
||||||
"from":clickNodeId,
|
|
||||||
"title":{'name':"Combination of parameters"},
|
|
||||||
"data":datas,
|
|
||||||
'style':{
|
|
||||||
'title-color':'#427b72',
|
|
||||||
'border-color':'#427b72',
|
|
||||||
'data-font-size':'10px',
|
|
||||||
'title-font-size':'12px'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let clickNodeX = Number(clickNode.getAttribute("x"));
|
|
||||||
let clickNodeY = Number(clickNode.getAttribute("y"));
|
|
||||||
graph.createNode(paramGraphData,clickNodeX,clickNodeY-100);
|
|
||||||
// graph.createNode(paramGraphData,e.x+150,e.y-30);
|
|
||||||
methodParamMap.set(clickNodeId+"ana","")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function formData(data) {
|
|
||||||
if (data['avgRunTime']>globalThreshold) {
|
|
||||||
data['style'] = {
|
|
||||||
'title-color':'#c71335',
|
|
||||||
'border-color':'#c71335',
|
|
||||||
'data-font-size':'10px',
|
|
||||||
'title-font-size':'12px'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
data['style'] = {
|
|
||||||
'title-color':'#375d46',
|
|
||||||
'border-color':'#375d46',
|
|
||||||
'data-font-size':'10px',
|
|
||||||
'title-font-size':'12px'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
data['title'] = {'name':data['name']};
|
|
||||||
data['data'] = [
|
|
||||||
{'name':'<span style="color:gray">type:</span>'+data['methodType']},
|
|
||||||
{'name':'<span style="color:gray">avg time:</span>'+data['avgRunTime']+' ms'},
|
|
||||||
{'name':'<span style="color:gray">max time:</span>'+data['maxRunTime']+' ms'},
|
|
||||||
{'name':'<span style="color:gray">min time:</span>'+data['minRunTime']+' ms'}
|
|
||||||
];
|
|
||||||
if (data['exceptionNum']!=null && data['exceptionNum']>0) {
|
|
||||||
data['data'].push({'name':'<span style="color:gray">number of exception:</span>'+data['exceptionNum']+' 个'});
|
|
||||||
}
|
|
||||||
data["dblclick"]="paramGraph";
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function showMethods(name) {
|
|
||||||
let exceptionDetailDom = document.getElementById('layerDemo');
|
|
||||||
exceptionDetailDom.innerHTML = "";
|
|
||||||
let options = {
|
|
||||||
'link-start-offsetx':8,
|
|
||||||
'link-start-offsety':0,
|
|
||||||
'link-end-offsetx':+10,
|
|
||||||
'link-end-offsety':0,
|
|
||||||
'link-width-offset':0
|
|
||||||
};
|
|
||||||
graph = new MetricFlow("layerDemo",options);
|
|
||||||
graph.threshold = globalThreshold;
|
|
||||||
UIkit.notification.closeAll();
|
|
||||||
UIkit.modal(document.getElementById("modal-method")).show();
|
|
||||||
|
|
||||||
$.get(contextPath+'/koTime/getTree?methodName=' + name+'&kotoken='+globalToken+"&project="+globalProject, function (data) {
|
|
||||||
let rootX = 100;
|
|
||||||
let rootY = $(window).get(0).innerHeight / 2-50;
|
|
||||||
data['x'] = rootX;
|
|
||||||
data['y'] = rootY;
|
|
||||||
graph.createNodes(data,formData);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
function showExceptions(id,message) {
|
|
||||||
$.get(contextPath+'/koTime/getMethodsByExceptionId?exceptionId=' + id+'&message='+message+'&kotoken='+globalToken+"&project="+globalProject, function (data) {
|
|
||||||
let html = '';
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
html +=
|
|
||||||
"<ul class=\"uk-list uk-list-divider\">\n" +
|
|
||||||
"\t<li id=\"exception-class\">Class:"+data[i].occurClassName+"</li>\n" +
|
|
||||||
"\t<li id=\"exception-method\">Method:"+data[i].methodName+"</li>\n" +
|
|
||||||
"\t<li id=\"exception-line\">Line:<span class=\"uk-label uk-label-success\">"+data[i].location+"</span></li>\n" +
|
|
||||||
"\t<li id=\"exception-message\">Exception message:<span class=\"uk-label uk-label-danger\">"+data[i].message+"</span></li>\n" +
|
|
||||||
"</ul>"
|
|
||||||
if (data.length-1>i) {
|
|
||||||
html +='<hr class="uk-divider-icon">'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let exceptionDetailDom = document.getElementById('exception-detail');
|
|
||||||
exceptionDetailDom.innerHTML = html;
|
|
||||||
UIkit.notification.closeAll();
|
|
||||||
UIkit.modal(document.getElementById("modal-exception")).show();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function login() {
|
|
||||||
let userId = $("#userName").val()
|
|
||||||
let password = $("#userPassword").val()
|
|
||||||
if (userId==undefined || userId.length<1 || password==undefined || password.length<1 ) {
|
|
||||||
UIkit.notification.closeAll()
|
|
||||||
UIkit.notification("<font color='red'>请正确输入用户名和密码</font>",{});
|
|
||||||
return
|
|
||||||
}
|
|
||||||
$.ajax({
|
|
||||||
type:'POST',
|
|
||||||
url:contextPath+"/koTime/login",
|
|
||||||
data:JSON.stringify({'userName':userId,'password':password}),
|
|
||||||
dataType:'json',
|
|
||||||
headers: {'Content-Type': 'application/json' },
|
|
||||||
success:function (re) {
|
|
||||||
if (re['state']==1) {
|
|
||||||
UIkit.notification("<font color='green'>Login was successful</font>",{});
|
|
||||||
UIkit.notification.closeAll()
|
|
||||||
sessionStorage.setItem("kotimeToken", re["token"]);
|
|
||||||
location.reload();
|
|
||||||
}else {
|
|
||||||
UIkit.notification("<font color='red'>Error user or password</font>",{});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error:function (re) {
|
|
||||||
console.log(re)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function searchTip(e){
|
|
||||||
let question = $('#searchText').val()
|
|
||||||
$.get(contextPath+'/koTime/getApiTips?question='+question+'&kotoken='+globalToken+"&project="+globalProject, function (data) {
|
|
||||||
$("#condidates").html("")
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
let name = data[i];
|
|
||||||
$("#condidates").append('<option value="'+name+'"/>');
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadProjects(){
|
|
||||||
$.get(contextPath+'/koTime/getProjects?kotoken='+globalToken+"&project=all", function (data) {
|
|
||||||
$("#projects").html("")
|
|
||||||
$("#projects").append('<option selected hidden disabled value="">Select you project</option>');
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
let name = data[i];
|
|
||||||
$("#projects").append(`<option value="${name}">${name}</option>`);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function searchApis(e) {
|
|
||||||
if (e.keyCode == 13) {
|
|
||||||
let question = $('#searchText').val()
|
|
||||||
$.get(contextPath+'/koTime/getApis?question='+question+'&kotoken='+globalToken+"&project="+globalProject, function (data) {
|
|
||||||
let element = document.getElementById('apiList');
|
|
||||||
html = '';
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
let id = data[i]['id'];
|
|
||||||
let className = data[i]['className'];
|
|
||||||
let methodName = data[i]['methodName'];
|
|
||||||
let avgRunTime = data[i]['avgRunTime'];
|
|
||||||
let methodType = data[i]['methodType'];
|
|
||||||
let routeName = data[i]['routeName'];
|
|
||||||
let apiId = className+"."+methodName;
|
|
||||||
let color = avgRunTime>globalThreshold?'danger':'success';
|
|
||||||
|
|
||||||
if (methodType=='Controller' && routeName!=null && routeName!='') {
|
|
||||||
html += "<li onclick=\"showMethods('"+id+"')\" style='color: #333;font-weight: 400;font-size: 14px;' id=\""+apiId+"-list\">"+ className+"#<span style='font-size: 16px;font-weight: 500;'>"+methodName+"</span> (<span style='font-size: 14px;font-weight: 430;color:#032b11'>"+routeName+"</span>)   <span style='font-size: 10px;' class=\"uk-label uk-label-"+color+"\">avg "+avgRunTime+" ms</span></li>";
|
|
||||||
}else{
|
|
||||||
html += "<li onclick=\"showMethods('"+id+"')\" style='color: #333;font-weight: 400;font-size: 14px;' id=\""+apiId+"-list\">"+ className+"#<span style='font-size: 16px;font-weight: 500;'>"+methodName+"</span>   <span style='font-size: 10px;' class=\"uk-label uk-label-"+color+"\">avg "+avgRunTime+" ms</span></li>";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
element.innerHTML = html;
|
|
||||||
});
|
|
||||||
$('#searchText').val('');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getProjectName(){
|
|
||||||
globalProject = document.querySelector("#projects").value;
|
|
||||||
loadStatistic();
|
|
||||||
loadApis();
|
|
||||||
loadExceptions();
|
|
||||||
}
|
|
||||||
@ -30,9 +30,26 @@ function post(url,data,successfun,errorFun) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function postFormData(url,data,successfun,errorFun) {
|
function put(url,data,successfun,errorFun) {
|
||||||
fetch(url, {
|
fetch(url, {
|
||||||
method: 'post',
|
method: 'put',
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
}).then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
successfun(json);
|
||||||
|
}).catch(e => {
|
||||||
|
if (errorFun) {
|
||||||
|
errorFun(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function putFormData(url,data,successfun,errorFun) {
|
||||||
|
fetch(url, {
|
||||||
|
method: 'put',
|
||||||
body: data
|
body: data
|
||||||
}).then(response => response.json())
|
}).then(response => response.json())
|
||||||
.then(json => {
|
.then(json => {
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
function refreshData() {
|
function refreshData() {
|
||||||
get(concatToken('contextPath/koTime/isLogin'), function (data) {
|
get(concatToken('contextPath/koTime/isLogin'), function (data) {
|
||||||
globalIsLogin = data['isLogin'] == 1 ? true : false;
|
globalIsLogin = data['content']['isLogin'] == 1 ? true : false;
|
||||||
if (globalNeedLogin == true && globalIsLogin == false) {
|
if (globalNeedLogin == true && globalIsLogin == false) {
|
||||||
UIkit.modal(getDom("modal-login")).show();
|
UIkit.modal(getDom("modal-login")).show();
|
||||||
return;
|
return;
|
||||||
@ -47,7 +47,15 @@
|
|||||||
loadExceptions();
|
loadExceptions();
|
||||||
loadCpuInfo();
|
loadCpuInfo();
|
||||||
loadHeapMemoryInfo();
|
loadHeapMemoryInfo();
|
||||||
|
loadNonHeapMemoryInfo();
|
||||||
loadPhysicalMemoryInfo();
|
loadPhysicalMemoryInfo();
|
||||||
|
loadEdenSpace();
|
||||||
|
loadSurvivorSpace();
|
||||||
|
loadOldGenSpace();
|
||||||
|
loadMetaspace();
|
||||||
|
loadGcUsage();
|
||||||
|
loadThreadUsage();
|
||||||
|
loadClassUsage();
|
||||||
loadThreadsInfo();
|
loadThreadsInfo();
|
||||||
loadDynamicProperties();
|
loadDynamicProperties();
|
||||||
}
|
}
|
||||||
@ -55,7 +63,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadExceptions() {
|
function loadExceptions() {
|
||||||
get(concatToken('contextPath/koTime/getExceptions'), function (data) {
|
get(concatToken('contextPath/koTime/exceptions'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入exceptions失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
let element = getDom('exceptionList');
|
let element = getDom('exceptionList');
|
||||||
html = '';
|
html = '';
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
@ -74,7 +87,12 @@
|
|||||||
let searchText = searchDom.value;
|
let searchText = searchDom.value;
|
||||||
let apiSortName = getDom('apiSortName')
|
let apiSortName = getDom('apiSortName')
|
||||||
let apiSortType = getDom('apiSortType')
|
let apiSortType = getDom('apiSortType')
|
||||||
get(concatToken(`contextPath/koTime/getApis?question=${searchText}&orderBy=${apiSortName.value}&sort=${apiSortType.value}`), function (data) {
|
get(concatToken(`contextPath/koTime/interfaces?question=${searchText}&orderBy=${apiSortName.value}&sort=${apiSortType.value}`), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入interfaces失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
searchDom.value='';
|
searchDom.value='';
|
||||||
let element = getDom('apiList');
|
let element = getDom('apiList');
|
||||||
html = '';
|
html = '';
|
||||||
@ -104,7 +122,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadStatistic() {
|
function loadStatistic() {
|
||||||
get(concatToken('contextPath/koTime/getStatistic'), function (data) {
|
get(concatToken('contextPath/koTime/interfaces/usage'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入interfaces/usage失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
let totalNum = data['totalNum'];
|
let totalNum = data['totalNum'];
|
||||||
let systemTotalNum = getDom("systemTotalNum");
|
let systemTotalNum = getDom("systemTotalNum");
|
||||||
systemTotalNum.innerHTML = totalNum;
|
systemTotalNum.innerHTML = totalNum;
|
||||||
@ -145,15 +168,27 @@
|
|||||||
getDom("systemMinRunTime").style.color = '#cc0c0c';
|
getDom("systemMinRunTime").style.color = '#cc0c0c';
|
||||||
} else {
|
} else {
|
||||||
getDom("systemMinRunTime").style.color = '#29da93';
|
getDom("systemMinRunTime").style.color = '#29da93';
|
||||||
}
|
};
|
||||||
;
|
|
||||||
|
let avgCallNum = data['avgCallNum'];
|
||||||
|
let systemAvgCallNumDom = getDom("systemAvgCallNum");
|
||||||
|
systemAvgCallNumDom.innerHTML = avgCallNum;
|
||||||
|
|
||||||
|
let minCallNum = data['minCallNum'];
|
||||||
|
let systemMinCallNumDom = getDom("systemMinCallNum");
|
||||||
|
systemMinCallNumDom.innerHTML = minCallNum;
|
||||||
|
|
||||||
|
|
||||||
|
let maxCallNum = data['maxCallNum'];
|
||||||
|
let systemMaxCallNumDom = getDom("systemMaxCallNum");
|
||||||
|
systemMaxCallNumDom.innerHTML = maxCallNum;
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addConfigEvent() {
|
function addConfigEvent() {
|
||||||
getDom('kotimeEnable').onclick = function () {
|
getDom('kotimeEnable').onclick = function () {
|
||||||
post(concatToken('contextPath/koTime/updateConfig'),{enable: getDom('kotimeEnable').checked},function (res) {
|
put(concatToken('contextPath/koTime/configs'),{enable: getDom('kotimeEnable').checked},function (res) {
|
||||||
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}');
|
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}');
|
||||||
},function () {
|
},function () {
|
||||||
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}');
|
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}');
|
||||||
@ -161,7 +196,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
getDom('exceptionEnable').onclick = function () {
|
getDom('exceptionEnable').onclick = function () {
|
||||||
post(concatToken('contextPath/koTime/updateConfig'),{exceptionEnable: getDom('exceptionEnable').checked},function (res) {
|
put(concatToken('contextPath/koTime/configs'),{exceptionEnable: getDom('exceptionEnable').checked},function (res) {
|
||||||
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
||||||
},function () {
|
},function () {
|
||||||
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
||||||
@ -169,7 +204,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
getDom('logEnable').onclick = function () {
|
getDom('logEnable').onclick = function () {
|
||||||
post(concatToken('contextPath/koTime/updateConfig'),{logEnable: getDom('logEnable').checked},function (res) {
|
put(concatToken('contextPath/koTime/configs'),{logEnable: getDom('logEnable').checked},function (res) {
|
||||||
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
||||||
},function () {
|
},function () {
|
||||||
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
||||||
@ -177,7 +212,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
getDom('mailEnable').onclick = function () {
|
getDom('mailEnable').onclick = function () {
|
||||||
post(concatToken('contextPath/koTime/updateConfig'),{mailEnable: getDom('mailEnable').checked},function (res) {
|
put(concatToken('contextPath/koTime/configs'),{mailEnable: getDom('mailEnable').checked},function (res) {
|
||||||
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
||||||
},function () {
|
},function () {
|
||||||
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
||||||
@ -185,7 +220,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
getDom('abbreviationEnable').onclick = function () {
|
getDom('abbreviationEnable').onclick = function () {
|
||||||
post(concatToken('contextPath/koTime/updateConfig'),{abbreviationEnable: getDom('abbreviationEnable').checked},function (res) {
|
put(concatToken('contextPath/koTime/configs'),{abbreviationEnable: getDom('abbreviationEnable').checked},function (res) {
|
||||||
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
||||||
},function () {
|
},function () {
|
||||||
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
||||||
@ -194,7 +229,7 @@
|
|||||||
|
|
||||||
getDom('languageSwitch').onclick = function () {
|
getDom('languageSwitch').onclick = function () {
|
||||||
let selectedObj = getDom('languageSwitch');
|
let selectedObj = getDom('languageSwitch');
|
||||||
post(concatToken('contextPath/koTime/updateConfig'),{language: selectedObj.options[selectedObj.selectedIndex].value},function (res) {
|
put(concatToken('contextPath/koTime/configs'),{language: selectedObj.options[selectedObj.selectedIndex].value},function (res) {
|
||||||
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
||||||
},function () {
|
},function () {
|
||||||
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
||||||
@ -202,7 +237,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
getDom('timeThresholdYes').onclick = function () {
|
getDom('timeThresholdYes').onclick = function () {
|
||||||
post(concatToken('contextPath/koTime/updateConfig'),{threshold: getDom('timeThreshold').value},function (res) {
|
put(concatToken('contextPath/koTime/configs'),{threshold: getDom('timeThreshold').value},function (res) {
|
||||||
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
noticeSuccess('{{tab.configuration.kotime-config.change-ok-tip}}')
|
||||||
},function () {
|
},function () {
|
||||||
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
noticeError('{{tab.configuration.kotime-config.change-fail-tip}}')
|
||||||
@ -220,7 +255,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadConfig() {
|
function loadConfig() {
|
||||||
get(concatToken('contextPath/koTime/getConfig'), function (data) {
|
get(concatToken('contextPath/koTime/configs'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入configs失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
let versionNoticeEnable = data['versionNotice'];
|
let versionNoticeEnable = data['versionNotice'];
|
||||||
if (versionNoticeEnable) {
|
if (versionNoticeEnable) {
|
||||||
loadLatestVersion();
|
loadLatestVersion();
|
||||||
@ -274,7 +314,12 @@
|
|||||||
graph.removeNode(clickNodeId + "ana")
|
graph.removeNode(clickNodeId + "ana")
|
||||||
methodParamMap.delete(clickNodeId + "ana")
|
methodParamMap.delete(clickNodeId + "ana")
|
||||||
} else {
|
} else {
|
||||||
get(concatToken('contextPath/koTime/getParamGraph' + "?methodId=" + clickNodeId.replace('node', '')), function (data) {
|
get(concatToken('contextPath/koTime/interfaces/'+clickNodeId.replace('node', '')+'/paramMetric'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入paramMetric失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
let datas = []
|
let datas = []
|
||||||
for (let key in data) {
|
for (let key in data) {
|
||||||
datas.push({"name": key + ":{{tab.interface.interface-list.show-metric.avg}} " + data[key]['avgRunTime'] + " ms"})
|
datas.push({"name": key + ":{{tab.interface.interface-list.show-metric.avg}} " + data[key]['avgRunTime'] + " ms"})
|
||||||
@ -334,7 +379,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function showMethods(name) {
|
function showMethods(methodId) {
|
||||||
let exceptionDetailDom = getDom('layerDemo');
|
let exceptionDetailDom = getDom('layerDemo');
|
||||||
exceptionDetailDom.innerHTML = "";
|
exceptionDetailDom.innerHTML = "";
|
||||||
let options = {
|
let options = {
|
||||||
@ -349,9 +394,14 @@
|
|||||||
UIkit.notification.closeAll();
|
UIkit.notification.closeAll();
|
||||||
UIkit.modal(getDom("modal-method")).show();
|
UIkit.modal(getDom("modal-method")).show();
|
||||||
|
|
||||||
get(concatToken('contextPath/koTime/getTree?methodName=' + name), function (data) {
|
get(concatToken('contextPath/koTime/interfaces/'+methodId+'/tree'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入tree失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
let rootX = 100;
|
let rootX = 100;
|
||||||
let rootY = $(window).get(0).innerHeight / 2 - 50;
|
let rootY = window.innerHeight / 2 - 50;
|
||||||
data['x'] = rootX;
|
data['x'] = rootX;
|
||||||
data['y'] = rootY;
|
data['y'] = rootY;
|
||||||
graph.createNodes(data, formData);
|
graph.createNodes(data, formData);
|
||||||
@ -361,7 +411,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
function showExceptions(id, message) {
|
function showExceptions(id, message) {
|
||||||
get(concatToken('contextPath/koTime/getMethodsByExceptionId?exceptionId=' + id + '&message=' + message), function (data) {
|
get(concatToken('contextPath/koTime/exceptions/' + id + '/details?message=' + message), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入tree失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
let html = '';
|
let html = '';
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
html +=
|
html +=
|
||||||
@ -394,7 +449,7 @@
|
|||||||
post("contextPath/koTime/login",{'userName': userId, 'password': password},function (re) {
|
post("contextPath/koTime/login",{'userName': userId, 'password': password},function (re) {
|
||||||
if (re['state'] == 1) {
|
if (re['state'] == 1) {
|
||||||
noticeSuccess('登录成功')
|
noticeSuccess('登录成功')
|
||||||
sessionStorage.setItem("kotimeToken", re["token"]);
|
sessionStorage.setItem("kotimeToken", re['content']["token"]);
|
||||||
location.reload();
|
location.reload();
|
||||||
} else {
|
} else {
|
||||||
noticeError('用户名或密码错误')
|
noticeError('用户名或密码错误')
|
||||||
@ -406,7 +461,12 @@
|
|||||||
|
|
||||||
function searchTip(e) {
|
function searchTip(e) {
|
||||||
let question = $('#searchText').val()
|
let question = $('#searchText').val()
|
||||||
get(concatToken('contextPath/koTime/getApiTips?question=' + question), function (data) {
|
get(concatToken('contextPath/koTime/interfaces/searchCondidate?question=' + question), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入interfaces/searchCondidate失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
$("#condidates").html("")
|
$("#condidates").html("")
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
let name = data[i];
|
let name = data[i];
|
||||||
@ -436,8 +496,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
formData.append('classFile', file);
|
formData.append('classFile', file);
|
||||||
formData.append('className', className);
|
putFormData(concatToken('contextPath/koTime/classes/'+className+'/replace'),formData,function (res) {
|
||||||
postFormData(concatToken('contextPath/koTime/updateClass'),formData,function (res) {
|
|
||||||
if (res['state'] == 1) {
|
if (res['state'] == 1) {
|
||||||
noticeSuccess('{{tab.hotupdate.change-ok-tip}}')
|
noticeSuccess('{{tab.hotupdate.change-ok-tip}}')
|
||||||
} else {
|
} else {
|
||||||
@ -455,7 +514,7 @@
|
|||||||
let propertiesDom = document.querySelector("#dynamicText");
|
let propertiesDom = document.querySelector("#dynamicText");
|
||||||
let propertiesText = propertiesDom.value;
|
let propertiesText = propertiesDom.value;
|
||||||
if (propertiesText && propertiesText.indexOf("=") > 0) {
|
if (propertiesText && propertiesText.indexOf("=") > 0) {
|
||||||
post(concatToken('contextPath/koTime/updateDynamicProperties'),{text: propertiesText},function (re) {
|
put(concatToken('contextPath/koTime/dynamicProperties'),{text: propertiesText.trim()},function (re) {
|
||||||
noticeSuccess('{{tab.configuration.dynamic-config.change-ok-tip}}')
|
noticeSuccess('{{tab.configuration.dynamic-config.change-ok-tip}}')
|
||||||
},function (re) {
|
},function (re) {
|
||||||
noticeError('{{tab.configuration.dynamic-config.change-fail-tip}}')
|
noticeError('{{tab.configuration.dynamic-config.change-fail-tip}}')
|
||||||
@ -467,8 +526,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadDynamicProperties() {
|
function loadDynamicProperties() {
|
||||||
get(concatToken('contextPath/koTime/getDynamicProperties'), function (data) {
|
get(concatToken('contextPath/koTime/dynamicProperties'), function (res) {
|
||||||
let text = data['data'];
|
let text = res['content'];
|
||||||
document.querySelector("#dynamicText").value = text;
|
document.querySelector("#dynamicText").value = text;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -484,7 +543,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadCpuInfo() {
|
function loadCpuInfo() {
|
||||||
get(concatToken('contextPath/koTime/getCpuInfo'), function (data) {
|
get(concatToken('contextPath/koTime/cpus/usage'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入cpus/usage失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
let systemLoad = data['systemLoad'] * 100;
|
let systemLoad = data['systemLoad'] * 100;
|
||||||
let userRate = data['userRate'] * 100;
|
let userRate = data['userRate'] * 100;
|
||||||
let sysRate = data['sysRate'] * 100;
|
let sysRate = data['sysRate'] * 100;
|
||||||
@ -501,12 +565,16 @@
|
|||||||
document.querySelector("#cpuSysRate").innerHTML = `${sysRate.toFixed(2)}%`;
|
document.querySelector("#cpuSysRate").innerHTML = `${sysRate.toFixed(2)}%`;
|
||||||
document.querySelector("#cpuUserRate").innerHTML = `${userRate.toFixed(2)}%`;
|
document.querySelector("#cpuUserRate").innerHTML = `${userRate.toFixed(2)}%`;
|
||||||
document.querySelector("#cpuLogicalAmount").innerHTML = `{{tab.summary.sysusage-metric.cpu-usage}}(${logicalNum}):`;
|
document.querySelector("#cpuLogicalAmount").innerHTML = `{{tab.summary.sysusage-metric.cpu-usage}}(${logicalNum}):`;
|
||||||
document.querySelector("#cpuWaitRate").innerHTML = `${waitRate.toFixed(2)}%`;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadHeapMemoryInfo() {
|
function loadHeapMemoryInfo() {
|
||||||
get(concatToken('contextPath/koTime/getHeapMemoryInfo'), function (data) {
|
get(concatToken('contextPath/koTime/memories/heap'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入memories/heap失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
// let initValue = data['initValue'] / 1024 / 1024;
|
// let initValue = data['initValue'] / 1024 / 1024;
|
||||||
// let maxValue = data['maxValue'] / 1024 / 1024;
|
// let maxValue = data['maxValue'] / 1024 / 1024;
|
||||||
// let usedValue = data['usedValue'] / 1024 / 1024;
|
// let usedValue = data['usedValue'] / 1024 / 1024;
|
||||||
@ -528,8 +596,42 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadNonHeapMemoryInfo() {
|
||||||
|
get(concatToken('contextPath/koTime/memories/nonHeap'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入memories/nonHeap失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
|
let initValue = getSize(data['initValue']);
|
||||||
|
let maxValue = getSize(data['maxValue']);
|
||||||
|
let usedValue = getSize(data['usedValue']);
|
||||||
|
let usedRate = data['usedRate'] * 100;
|
||||||
|
var nonheapUsedRateDom = document.querySelector("#nonHeapUsedRate");
|
||||||
|
if (usedRate > 50) {
|
||||||
|
nonheapUsedRateDom.style.color = '#cc0c0c';
|
||||||
|
} else {
|
||||||
|
nonheapUsedRateDom.style.color = '#29da93';
|
||||||
|
}
|
||||||
|
;
|
||||||
|
document.querySelector("#nonHeapInit").innerHTML = initValue;
|
||||||
|
document.querySelector("#nonHeapMax").innerHTML = maxValue;
|
||||||
|
document.querySelector("#nonHeapUsed").innerHTML = usedValue;
|
||||||
|
if (data['maxValue']==-1) {
|
||||||
|
nonheapUsedRateDom.innerHTML = `-%`;
|
||||||
|
}else {
|
||||||
|
nonheapUsedRateDom.innerHTML = `${usedRate.toFixed(2)}%`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function loadPhysicalMemoryInfo() {
|
function loadPhysicalMemoryInfo() {
|
||||||
get(concatToken('contextPath/koTime/getPhysicalMemoryInfo'), function (data) {
|
get(concatToken('contextPath/koTime/memories/physical'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入memories/physical失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
// let initValue = data['initValue'] / 1024 / 1024;
|
// let initValue = data['initValue'] / 1024 / 1024;
|
||||||
// let thisUsedValue = data['thisUsedValue'] / 1024 / 1024;
|
// let thisUsedValue = data['thisUsedValue'] / 1024 / 1024;
|
||||||
// let usedValue = data['usedValue'] / 1024 / 1024;
|
// let usedValue = data['usedValue'] / 1024 / 1024;
|
||||||
@ -553,6 +655,171 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadEdenSpace() {
|
||||||
|
get(concatToken('contextPath/koTime/jvmSpaces/edenSpace'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载jvmSpaces/edenSpace失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
|
let initValue = getSize(data['initValue']);
|
||||||
|
let maxValue = getSize(data['maxValue']);
|
||||||
|
let usedValue = getSize(data['usedValue']);
|
||||||
|
let usedRate = data['usedRate'] * 100;
|
||||||
|
let edenSpaceUsedRateDom = document.querySelector("#edenSpaceUsedRate");
|
||||||
|
if (usedRate > 50) {
|
||||||
|
edenSpaceUsedRateDom.style.color = '#cc0c0c';
|
||||||
|
} else {
|
||||||
|
edenSpaceUsedRateDom.style.color = '#29da93';
|
||||||
|
}
|
||||||
|
;
|
||||||
|
document.querySelector("#edenSpaceInit").innerHTML = initValue;
|
||||||
|
document.querySelector("#edenSpaceMax").innerHTML = maxValue;
|
||||||
|
document.querySelector("#edenSpaceUsed").innerHTML = usedValue;
|
||||||
|
edenSpaceUsedRateDom.innerHTML = `${usedRate.toFixed(2)}%`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSurvivorSpace() {
|
||||||
|
get(concatToken('contextPath/koTime/jvmSpaces/survivorSpace'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载jvmSpaces/survivorSpace失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
|
let initValue = getSize(data['initValue']);
|
||||||
|
let maxValue = getSize(data['maxValue']);
|
||||||
|
let usedValue = getSize(data['usedValue']);
|
||||||
|
let usedRate = data['usedRate'] * 100;
|
||||||
|
let survivorSpaceUsedRateDom = document.querySelector("#survivorSpaceUsedRate");
|
||||||
|
if (usedRate > 50) {
|
||||||
|
survivorSpaceUsedRateDom.style.color = '#cc0c0c';
|
||||||
|
} else {
|
||||||
|
survivorSpaceUsedRateDom.style.color = '#29da93';
|
||||||
|
}
|
||||||
|
;
|
||||||
|
document.querySelector("#survivorSpaceInit").innerHTML = initValue;
|
||||||
|
document.querySelector("#survivorSpaceMax").innerHTML = maxValue;
|
||||||
|
document.querySelector("#survivorSpaceUsed").innerHTML = usedValue;
|
||||||
|
survivorSpaceUsedRateDom.innerHTML = `${usedRate.toFixed(2)}%`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadOldGenSpace() {
|
||||||
|
get(concatToken('contextPath/koTime/jvmSpaces/oldGen'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载jvmSpaces/oldGen失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
|
let initValue = getSize(data['initValue']);
|
||||||
|
let maxValue = getSize(data['maxValue']);
|
||||||
|
let usedValue = getSize(data['usedValue']);
|
||||||
|
let usedRate = data['usedRate'] * 100;
|
||||||
|
let oldGenUsedRateDom = document.querySelector("#oldGenUsedRate");
|
||||||
|
if (usedRate > 50) {
|
||||||
|
oldGenUsedRateDom.style.color = '#cc0c0c';
|
||||||
|
} else {
|
||||||
|
oldGenUsedRateDom.style.color = '#29da93';
|
||||||
|
}
|
||||||
|
;
|
||||||
|
document.querySelector("#oldGenInit").innerHTML = initValue;
|
||||||
|
document.querySelector("#oldGenMax").innerHTML = maxValue;
|
||||||
|
document.querySelector("#oldGenUsed").innerHTML = usedValue;
|
||||||
|
oldGenUsedRateDom.innerHTML = `${usedRate.toFixed(2)}%`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadMetaspace() {
|
||||||
|
get(concatToken('contextPath/koTime/jvmSpaces/metaspace'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载jvmSpaces/metaspace失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
|
let initValue = getSize(data['initValue']);
|
||||||
|
let maxValue = getSize(data['maxValue']);
|
||||||
|
let usedValue = getSize(data['usedValue']);
|
||||||
|
let usedRate = data['usedRate'] * 100;
|
||||||
|
let metaspaceUsedRateDom = document.querySelector("#metaspaceUsedRate");
|
||||||
|
if (usedRate > 50) {
|
||||||
|
metaspaceUsedRateDom.style.color = '#cc0c0c';
|
||||||
|
} else {
|
||||||
|
metaspaceUsedRateDom.style.color = '#29da93';
|
||||||
|
}
|
||||||
|
;
|
||||||
|
document.querySelector("#metaspaceInit").innerHTML = initValue;
|
||||||
|
document.querySelector("#metaspaceMax").innerHTML = maxValue;
|
||||||
|
document.querySelector("#metaspaceUsed").innerHTML = usedValue;
|
||||||
|
if (data['maxValue']==-1) {
|
||||||
|
metaspaceUsedRateDom.innerHTML = `-%`;
|
||||||
|
}else {
|
||||||
|
metaspaceUsedRateDom.innerHTML = `${usedRate.toFixed(2)}%`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadGcUsage() {
|
||||||
|
get(concatToken('contextPath/koTime/gcs/usage'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载gcs/usage失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
|
let totalNum = data['totalNum'];
|
||||||
|
let fullNum = data['fullNum'];
|
||||||
|
let minorNum = data['minorNum'];
|
||||||
|
|
||||||
|
document.querySelector("#gcTotalNum").innerHTML = totalNum;
|
||||||
|
document.querySelector("#gcMinorNum").innerHTML = minorNum;
|
||||||
|
document.querySelector("#gcFullNum").innerHTML = fullNum;
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThreadUsage() {
|
||||||
|
get(concatToken('contextPath/koTime/threads/usage'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载threads/usage失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
|
let totalNum = data['totalNum'];
|
||||||
|
let runnableNum = data['runnableNum'];
|
||||||
|
let deadlockNum = data['deadLockNum'];
|
||||||
|
|
||||||
|
let threadLockNumDom = document.querySelector("#threadLockNum");
|
||||||
|
if (deadlockNum > 0) {
|
||||||
|
threadLockNumDom.style.color = '#cc0c0c';
|
||||||
|
} else {
|
||||||
|
threadLockNumDom.style.color = '#29da93';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector("#threadTotalNum").innerHTML = totalNum;
|
||||||
|
document.querySelector("#threadRunnableNum").innerHTML = runnableNum;
|
||||||
|
threadLockNumDom.innerHTML = deadlockNum;
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadClassUsage() {
|
||||||
|
get(concatToken('contextPath/koTime/classes/usage'), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载classes/usage失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
|
let totalNum = data['totalClassNum'];
|
||||||
|
let currentClassNum = data['currentClassNum'];
|
||||||
|
let unloadedClassNum = data['unloadedClassNum'];
|
||||||
|
|
||||||
|
document.querySelector("#classTotalNum").innerHTML = totalNum;
|
||||||
|
document.querySelector("#classCurrentNum").innerHTML = currentClassNum;
|
||||||
|
document.querySelector("#classDeleteNum").innerHTML = unloadedClassNum;
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const cpuUsageColorMap = {
|
const cpuUsageColorMap = {
|
||||||
'RED': '#cc0c0c',
|
'RED': '#cc0c0c',
|
||||||
'YELLOW': '#f0ad4e',
|
'YELLOW': '#f0ad4e',
|
||||||
@ -573,7 +840,12 @@
|
|||||||
|
|
||||||
function loadThreadsInfo(queryState) {
|
function loadThreadsInfo(queryState) {
|
||||||
queryState = queryState || '';
|
queryState = queryState || '';
|
||||||
get(concatToken('contextPath/koTime/getThreadsInfo?state=' + queryState), function (data) {
|
get(concatToken('contextPath/koTime/threads?state=' + queryState), function (res) {
|
||||||
|
if (res['state']==0) {
|
||||||
|
noticeError("载入threads失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = res['content'];
|
||||||
let statistics = data['statistics'];
|
let statistics = data['statistics'];
|
||||||
let all = statistics['all'];
|
let all = statistics['all'];
|
||||||
let RUNNABLE = statistics['RUNNABLE'] || 0;
|
let RUNNABLE = statistics['RUNNABLE'] || 0;
|
||||||
@ -592,9 +864,9 @@
|
|||||||
let threads = data['threads'];
|
let threads = data['threads'];
|
||||||
let colors = {
|
let colors = {
|
||||||
'RUNNABLE': '#32d296',
|
'RUNNABLE': '#32d296',
|
||||||
'BLOCKED': '#cc0c0c',
|
'BLOCKED': '#e0ce86',
|
||||||
'WAITING': '#ad7070',
|
'WAITING': '#eec793',
|
||||||
'TIMED_WAITING': '#ad7070'
|
'TIMED_WAITING': '#d99292'
|
||||||
}
|
}
|
||||||
for (let i = 0; i < threads.length; i++) {
|
for (let i = 0; i < threads.length; i++) {
|
||||||
let thread = threads[i];
|
let thread = threads[i];
|
||||||
@ -604,9 +876,14 @@
|
|||||||
let state = thread['state'];
|
let state = thread['state'];
|
||||||
let stacks = thread['stacks'];
|
let stacks = thread['stacks'];
|
||||||
let cpuUsage = thread['cpuUsage'];
|
let cpuUsage = thread['cpuUsage'];
|
||||||
|
let deadLock = thread['deadLock'];
|
||||||
let cpuUsageColor = getCpuUsageColor(cpuUsage);
|
let cpuUsageColor = getCpuUsageColor(cpuUsage);
|
||||||
threadMap[id + ''] = stacks;
|
threadMap[id + ''] = stacks;
|
||||||
html += `<li onclick="showThreadInfo('${id}')" class='common-li'>id=<span style="font-size: 16px;font-weight: 500;">${id}</span> name=${name} class=${classType} <span style="font-size: 10px;background-color: ${cpuUsageColor};" class="uk-label uk-label-success">{{tab.thread.thread-list.cpu-usage}}:${cpuUsage}%</span> <span style='font-size: 10px;background-color: ${colors[state]};' class="uk-label uk-label-success">${state}</span></li>`;
|
if (deadLock) {
|
||||||
|
html += `<li onclick="showThreadInfo('${id}')" class='common-li'>id=<span style="font-size: 16px;font-weight: 500;">${id}</span> name=${name} class=${classType} <span style="font-size: 10px;background-color: ${cpuUsageColor};" class="uk-label uk-label-success">{{tab.thread.thread-list.cpu-usage}}:${cpuUsage}%</span> <span style='font-size: 10px;background-color: ${colors[state]};' class="uk-label uk-label-success">${state}</span> <span style='font-size: 10px;background-color: #ec2147;' class="uk-label">DEADLOCK</span></li>`;
|
||||||
|
}else {
|
||||||
|
html += `<li onclick="showThreadInfo('${id}')" class='common-li'>id=<span style="font-size: 16px;font-weight: 500;">${id}</span> name=${name} class=${classType} <span style="font-size: 10px;background-color: ${cpuUsageColor};" class="uk-label uk-label-success">{{tab.thread.thread-list.cpu-usage}}:${cpuUsage}%</span> <span style='font-size: 10px;background-color: ${colors[state]};' class="uk-label uk-label-success">${state}</span></li>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
element.innerHTML = html;
|
element.innerHTML = html;
|
||||||
});
|
});
|
||||||
@ -638,7 +915,16 @@
|
|||||||
let searchText = searchDom.value;
|
let searchText = searchDom.value;
|
||||||
let apiSortName = getDom('apiSortName')
|
let apiSortName = getDom('apiSortName')
|
||||||
let apiSortType = getDom('apiSortType')
|
let apiSortType = getDom('apiSortType')
|
||||||
let url = concatToken(`contextPath/koTime/exportApis?question=${searchText}&orderBy=${apiSortName.value}&sort=${apiSortType.value}`);
|
let url = concatToken(`contextPath/koTime/interfaces/export?question=${searchText}&orderBy=${apiSortName.value}&sort=${apiSortType.value}`);
|
||||||
|
let a = document.createElement("a");
|
||||||
|
a.style.display='none';
|
||||||
|
a.href = url;
|
||||||
|
a.click();
|
||||||
|
setTimeout(()=>{a.remove();},3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dumpHeap() {
|
||||||
|
let url = concatToken(`contextPath/koTime/memories/heap/export`);
|
||||||
let a = document.createElement("a");
|
let a = document.createElement("a");
|
||||||
a.style.display='none';
|
a.style.display='none';
|
||||||
a.href = url;
|
a.href = url;
|
||||||
@ -682,116 +968,173 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul class="uk-switcher uk-margin">
|
<ul class="uk-switcher uk-margin">
|
||||||
<li style="margin-left: 30%;margin-right: 30%;margin-top: -10px">
|
<li style="margin-left: 28%;margin-right: 28%;margin-top: -10px">
|
||||||
<ul class="uk-flex-left" uk-tab>
|
<ul class="uk-flex-left" uk-tab>
|
||||||
<li class="uk-active"><a style="text-transform: unset" href="#">{{tab.summary.interface-metric}}</a></li>
|
<li class="uk-active"><a style="text-transform: unset" href="#">{{tab.summary.interface-metric}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div style="margin-top: 20px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
<div style="margin-top: 10px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
||||||
<div>
|
<div>
|
||||||
<div id="systemTotalNum-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
<div id="systemNum-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span class="metric-card-summary-n">{{tab.summary.interface-metric.total-num}}:</span><span class="metric-card-summary-v" id="systemTotalNum">0</span>
|
||||||
<span style="font-size: 10px;color: #3b3f4f">{{tab.summary.interface-metric.total-num}}</span><br>
|
<hr style="margin-top: 7px">
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="systemTotalNum">0</span>
|
<ul class="uk-list metric-card-item">
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.interface-metric.delay-num}}:</span><span class="metric-card-item-v" id="systemDelayNum">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.interface-metric.normal-num}}:</span><span class="metric-card-item-v" id="systemNormalNum">0</span></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id="systemDelayNum-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
<div id="systemRunTime-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span class="metric-card-summary-n">{{tab.summary.response-metric.avg-num}}:</span><span class="metric-card-summary-v" id="systemAvgRunTime">0</span>
|
||||||
<span style="font-size: 10px;color: #3b3f4f">{{tab.summary.interface-metric.delay-num}}</span>
|
<hr style="margin-top: 7px">
|
||||||
<br>
|
<ul class="uk-list metric-card-item">
|
||||||
<span style="font-size: 30px;color: #cc0c0c;font-weight: bold" id="systemDelayNum">0</span>
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.response-metric.max-num}}:</span><span class="metric-card-item-v" id="systemMaxRunTime">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.response-metric.min-num}}:</span><span class="metric-card-item-v" id="systemMinRunTime">0</span></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id="systemNormalNum-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
<div id="systemCallNum-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span class="metric-card-summary-n">{{tab.summary.interface-metric.avg-call-num}}:</span><span class="metric-card-summary-v" id="systemAvgCallNum">0</span>
|
||||||
<span style="font-size: 10px;color: #3b3f4f">{{tab.summary.interface-metric.normal-num}}</span>
|
<hr style="margin-top: 7px">
|
||||||
<br>
|
<ul class="uk-list metric-card-item">
|
||||||
<span style="font-size: 30px;color: #29da93;font-weight: bold" id="systemNormalNum">0</span></div>
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.interface-metric.max-call-num}}:</span><span class="metric-card-item-v" id="systemMaxCallNum">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.interface-metric.min-call-num}}:</span><span class="metric-card-item-v" id="systemMinCallNum">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul style="margin-top: 10px;" class="uk-flex-left" uk-tab>
|
<ul style="margin-top: 10px;" class="uk-flex-left" uk-tab>
|
||||||
<li class="uk-active"><a style="text-transform: unset" href="#">{{tab.summary.response-metric}}</a></li>
|
<li class="uk-active"><a style="text-transform: unset" href="#">{{tab.summary.memory-metric}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div style="margin-top: 10px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
<div style="margin-top: 10px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
||||||
<div>
|
<div>
|
||||||
<div id="systemAvgRunTime-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
<div id="physicalMemory-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.physical-memory}}:</span><span class="metric-card-summary-v" id="physicalUsedRate">0</span>
|
||||||
<span style="font-size: 10px;color: #3b3f4f">{{tab.summary.response-metric.avg-num}}</span>
|
<hr style="margin-top: 7px">
|
||||||
<br>
|
<ul class="uk-list metric-card-item">
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="systemAvgRunTime">0</span></div>
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.physical-memory.total}}:</span><span class="metric-card-item-v" id="physicalAmount">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.physical-memory.used}}:</span><span class="metric-card-item-v" id="physicalUsed">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.physical-memory.current-used}}:</span><span class="metric-card-item-v" id="thisUsed">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id="systemMaxRunTime-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
<div id="heapMemory-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span onclick="dumpHeap();" style="text-transform: unset;background-color: #404b67;position: absolute;cursor: pointer" title="dump" class="uk-card-badge">></span>
|
||||||
<span style="font-size: 10px;color: #3b3f4f">{{tab.summary.response-metric.max-num}}</span>
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.heap-memory}}:</span><span class="metric-card-summary-v" id="heapUsedRate">0</span>
|
||||||
<br>
|
<hr style="margin-top: 7px">
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="systemMaxRunTime">0</span></div>
|
<ul class="uk-list metric-card-item">
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.init}}:</span><span class="metric-card-item-v" id="heapInit">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.max}}:</span><span class="metric-card-item-v" id="heapMax">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.used}}:</span><span class="metric-card-item-v" id="heapUsed">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id="systemMinRunTime-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
<div id="nonHeapMemory-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.non-heap-memory}}:</span><span class="metric-card-summary-v" id="nonHeapUsedRate">0</span>
|
||||||
<span style="font-size: 10px;color: #3b3f4f">{{tab.summary.response-metric.min-num}}</span>
|
<hr style="margin-top: 7px">
|
||||||
<br>
|
<ul class="uk-list metric-card-item">
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="systemMinRunTime">0</span></div>
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.init}}:</span><span class="metric-card-item-v" id="nonHeapInit">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.max}}:</span><span class="metric-card-item-v" id="nonHeapMax">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.used}}:</span><span class="metric-card-item-v" id="nonHeapUsed">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul style="margin-top: 10px;" class="uk-flex-left" uk-tab>
|
||||||
|
<li class="uk-active"><a style="text-transform: unset" href="#">{{tab.summary.jvm-metric}}</a></li>
|
||||||
|
</ul>
|
||||||
|
<div style="margin-top: 10px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
||||||
|
<div>
|
||||||
|
<div id="EdenSpace-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.eden-space}}:</span><span class="metric-card-summary-v" id="edenSpaceUsedRate">0</span>
|
||||||
|
<hr style="margin-top: 7px">
|
||||||
|
<ul class="uk-list metric-card-item">
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.init}}:</span><span class="metric-card-item-v" id="edenSpaceInit">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.max}}: </span><span class="metric-card-item-v" id="edenSpaceMax">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.used}}:</span><span class="metric-card-item-v" id="edenSpaceUsed">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div id="SurvivorSpace-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.survivor-space}}:</span><span class="metric-card-summary-v" id="survivorSpaceUsedRate">0</span>
|
||||||
|
<hr style="margin-top: 7px">
|
||||||
|
<ul class="uk-list metric-card-item">
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.init}}:</span><span class="metric-card-item-v" id="survivorSpaceInit">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.max}}: </span><span class="metric-card-item-v" id="survivorSpaceMax">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.used}}:</span><span class="metric-card-item-v" id="survivorSpaceUsed">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div id="OldGen-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.old-gen}}:</span><span class="metric-card-summary-v" id="oldGenUsedRate">0</span>
|
||||||
|
<hr style="margin-top: 7px">
|
||||||
|
<ul class="uk-list metric-card-item">
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.init}}:</span><span class="metric-card-item-v" id="oldGenInit">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.max}}: </span><span class="metric-card-item-v" id="oldGenMax">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.used}}:</span><span class="metric-card-item-v" id="oldGenUsed">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div id="Metaspace-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.meta-space}}:</span><span class="metric-card-summary-v" id="metaspaceUsedRate">0</span>
|
||||||
|
<hr style="margin-top: 7px">
|
||||||
|
<ul class="uk-list metric-card-item">
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.init}}:</span><span class="metric-card-item-v" id="metaspaceInit">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.max}}: </span><span class="metric-card-item-v" id="metaspaceMax">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.heap-memory.used}}:</span><span class="metric-card-item-v" id="metaspaceUsed">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="uk-flex-left" uk-tab>
|
<ul class="uk-flex-left" uk-tab>
|
||||||
<li class="uk-active"><a style="text-transform: unset" href="#">{{tab.summary.sysusage-metric}}</a></li>
|
<li class="uk-active"><a style="text-transform: unset" href="#">{{tab.summary.other-metric}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div style="margin-top: 20px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
<div style="margin-top: 10px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
||||||
<div>
|
<div>
|
||||||
<div id="cpuInfo-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px; text-align: left;"
|
<div id="cpuInfo-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span id="cpuLogicalAmount" class="metric-card-summary-n">{{tab.summary.sysusage-metric.cpu-usage}}:</span><span class="metric-card-summary-v" id="systemLoad">0</span>
|
||||||
<span style="font-size: 12px;color: #3b3f4f;justify-content: space-around;" id="cpuLogicalAmount">{{tab.summary.sysusage-metric.cpu-usage}}:</span><span
|
|
||||||
style="font-size: 15px;color: #020718;font-weight: bold" id="systemLoad">0</span>
|
|
||||||
<hr style="margin-top: 7px">
|
<hr style="margin-top: 7px">
|
||||||
<ul class="uk-list-bullet" style="text-align: left;margin-top: -13px; margin-left: -40px;list-style-type: none">
|
<ul class="uk-list metric-card-item">
|
||||||
<li style="margin-top: -2px;"><span
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.cpu-usage.user-usage}}:</span><span class="metric-card-item-v" id="cpuUserRate">0</span></li>
|
||||||
style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.cpu-usage.user-usage}}:</span><span
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.cpu-usage.sys-usage}}:</span><span class="metric-card-item-v" id="cpuSysRate">0</span></li>
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="cpuUserRate">0</span></li>
|
|
||||||
<li style="margin-top: -2px;"><span
|
|
||||||
style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.cpu-usage.sys-usage}}:</span><span
|
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="cpuSysRate">0</span></li>
|
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.cpu-usage.io-waiting}}:</span><span
|
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="cpuWaitRate">0</span></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id="heapMemory-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px; text-align: left;"
|
<div id="gc-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.gc-num}}:</span><span class="metric-card-summary-v" id="gcTotalNum">0</span>
|
||||||
<span style="font-size: 12px;color: #3b3f4f;justify-content: space-around;">{{tab.summary.sysusage-metric.heap-memory}}:</span><span
|
|
||||||
style="font-size: 15px;color: #020718;font-weight: bold" id="heapUsedRate">0</span>
|
|
||||||
<hr style="margin-top: 7px">
|
<hr style="margin-top: 7px">
|
||||||
<ul class="uk-list-bullet" style="text-align: left;margin-top: -13px; margin-left: -40px;list-style-type: none">
|
<ul class="uk-list metric-card-item">
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.heap-memory.init}}:</span><span
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.gc-num.minor}}:</span><span class="metric-card-item-v" id="gcMinorNum">0</span></li>
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="heapInit">0</span></li>
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.gc-num.full}}:</span><span class="metric-card-item-v" id="gcFullNum">0</span></li>
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.heap-memory.max}}:</span><span
|
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="heapMax">0</span></li>
|
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.heap-memory.used}}:</span><span
|
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="heapUsed">0</span></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id="physicalMemory-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px; text-align: left;"
|
<div id="thread-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
class="uk-card uk-card-default uk-card-body uk-label-success">
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.thread-num}}:</span><span class="metric-card-summary-v" id="threadTotalNum">0</span>
|
||||||
<span style="font-size: 12px;color: #3b3f4f;justify-content: space-around;">{{tab.summary.sysusage-metric.physical-memory}}:</span><span
|
|
||||||
style="font-size: 15px;color: #020718;font-weight: bold" id="physicalUsedRate">0</span>
|
|
||||||
<hr style="margin-top: 7px">
|
<hr style="margin-top: 7px">
|
||||||
<ul class="uk-list-bullet" style="text-align: left;margin-top: -13px; margin-left: -40px;list-style-type: none">
|
<ul class="uk-list metric-card-item">
|
||||||
<li style="margin-top: -2px;"><span
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.thread-num.runnable}}:</span><span class="metric-card-item-v" id="threadRunnableNum">0</span></li>
|
||||||
style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.physical-memory.total}}:</span><span
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.thread-num.deadlock}}:</span><span class="metric-card-item-v" id="threadLockNum">0</span></li>
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="physicalAmount">0</span>
|
</ul>
|
||||||
</li>
|
</div>
|
||||||
<li style="margin-top: -2px;"><span
|
</div>
|
||||||
style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.physical-memory.used}}:</span><span
|
<div>
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="physicalUsed">0</span></li>
|
<div id="class-div" class="uk-card uk-card-default uk-card-body uk-label-success metric-card">
|
||||||
<li style="margin-top: -2px;"><span
|
<span class="metric-card-summary-n">{{tab.summary.sysusage-metric.loaded-class-num}}:</span><span class="metric-card-summary-v" id="classTotalNum">0</span>
|
||||||
style="font-size: 8px;color: #3b3f4f;">{{tab.summary.sysusage-metric.physical-memory.current-used}}:</span><span
|
<hr style="margin-top: 7px">
|
||||||
style="font-size: 12px;color: #020718;font-weight: bold" id="thisUsed">0</span></li>
|
<ul class="uk-list metric-card-item">
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.loaded-class-num.current}}:</span><span class="metric-card-item-v" id="classCurrentNum">0</span></li>
|
||||||
|
<li><div class="metric-card-item-point"></div><span class="metric-card-item-n">{{tab.summary.sysusage-metric.loaded-class-num.unloaded}}:</span><span class="metric-card-item-v" id="classDeleteNum">0</span></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user