mirror of
https://gitee.com/huoyo/ko-time.git
synced 2025-12-06 16:58:26 +08:00
add:load index.html from the static configurations
This commit is contained in:
parent
0d69b3eab8
commit
94411eb3a8
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ target/
|
|||||||
.txlcn
|
.txlcn
|
||||||
*.log
|
*.log
|
||||||
/.idea/
|
/.idea/
|
||||||
|
/.idea/
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>cn.langpy</groupId>
|
<groupId>cn.langpy</groupId>
|
||||||
<artifactId>ko-time</artifactId>
|
<artifactId>ko-time</artifactId>
|
||||||
<version>2.4.4</version>
|
<version>2.4.5</version>
|
||||||
<name>KoTime</name>
|
<name>KoTime</name>
|
||||||
<description>A springboot tool for tracking the paths of the methods,which can help you find method's performances easily.</description>
|
<description>A springboot tool for tracking the paths of the methods,which can help you find method's performances easily.</description>
|
||||||
<licenses>
|
<licenses>
|
||||||
|
|||||||
@ -9,12 +9,11 @@ public class KoConstant {
|
|||||||
public final static String exceptionTitleStyle = "exceptionTitleStyle";
|
public final static String exceptionTitleStyle = "exceptionTitleStyle";
|
||||||
public final static String globalThreshold = "globalThresholdValue";
|
public final static String globalThreshold = "globalThresholdValue";
|
||||||
public final static String globalNeedLogin = "globalNeedLoginValue";
|
public final static String globalNeedLogin = "globalNeedLoginValue";
|
||||||
public final static String globalIsLogin = "globalIsLoginValue";
|
|
||||||
public final static String contextPath = "contextPath";
|
public final static String contextPath = "contextPath";
|
||||||
public final static String kotimeViewer = "kotime.html";
|
public final static String kotimeViewer = "kotime.html";
|
||||||
public final static String kotimeViewerEn = "kotime-en.html";
|
public final static String kotimeViewerEn = "kotime-en.html";
|
||||||
public final static String loginName = "kotimeUserName";
|
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static String getViewName(String language) {
|
public static String getViewName(String language) {
|
||||||
if (!StringUtils.hasText(language)) {
|
if (!StringUtils.hasText(language)) {
|
||||||
language = Context.getConfig().getLanguage();
|
language = Context.getConfig().getLanguage();
|
||||||
|
|||||||
188
src/main/java/cn/langpy/kotime/controller/KoInitController.java
Normal file
188
src/main/java/cn/langpy/kotime/controller/KoInitController.java
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
package cn.langpy.kotime.controller;
|
||||||
|
|
||||||
|
import cn.langpy.kotime.constant.KoConstant;
|
||||||
|
import cn.langpy.kotime.model.*;
|
||||||
|
import cn.langpy.kotime.util.Context;
|
||||||
|
import cn.langpy.kotime.util.InvalidAuthInfoException;
|
||||||
|
import cn.langpy.kotime.util.KoUtil;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zhangchang
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/koTime")
|
||||||
|
public class KoInitController {
|
||||||
|
private static Logger log = Logger.getLogger(KoInitController.class.toString());
|
||||||
|
|
||||||
|
@Value("${ko-time.user-name:}")
|
||||||
|
private String userName;
|
||||||
|
@Value("${ko-time.password:}")
|
||||||
|
private String password;
|
||||||
|
private final Pattern pattern = Pattern.compile("\\{\\{[a-zA-Z0-9\\.-]+\\}\\}");
|
||||||
|
|
||||||
|
private final String uiKitCssText = getResourceText("kostatic/uikit.min.css");
|
||||||
|
private final String uiKitJsText = getResourceText("kostatic/uikit.min.js");
|
||||||
|
private final String metricFlowJsText = getResourceText("kostatic/Metricflow.js");
|
||||||
|
private final String jQueryJsText = getResourceText("kostatic/JQuery.min.js");
|
||||||
|
private final String uiKitIconsJs = getResourceText("kostatic/uikit-icons.js");
|
||||||
|
private final String KoTimeUtil = getResourceText("kostatic/util.js");
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
@ResponseBody
|
||||||
|
public Map login(@RequestBody UserInfo userInfo) {
|
||||||
|
if (null == userInfo || !StringUtils.hasText(userInfo.getUserName()) || !StringUtils.hasText(userInfo.getPassword())) {
|
||||||
|
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())) {
|
||||||
|
String token = KoUtil.login(userInfo.getUserName());
|
||||||
|
map.put("state", 1);
|
||||||
|
map.put("token", token);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
map.put("state", 0);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/isLogin")
|
||||||
|
@ResponseBody
|
||||||
|
public Map isLogin(String kotoken) {
|
||||||
|
Map map = new HashMap();
|
||||||
|
map.put("state", 1);
|
||||||
|
boolean checkLogin = false;
|
||||||
|
if (StringUtils.hasText(kotoken)) {
|
||||||
|
if (kotoken.equals(Context.getConfig().getStaticToken())) {
|
||||||
|
checkLogin = true;
|
||||||
|
} else {
|
||||||
|
checkLogin = KoUtil.isLogin(kotoken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.put("isLogin", checkLogin ? 1 : 0);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public void index(String kotoken, String charset, String language, HttpServletResponse response, HttpServletRequest request) {
|
||||||
|
if (!Context.getConfig().getEnable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(charset)) {
|
||||||
|
charset = "utf-8";
|
||||||
|
}
|
||||||
|
response.setContentType("text/html;charset=" + charset);
|
||||||
|
ClassPathResource classPathResource = new ClassPathResource(KoConstant.kotimeViewer);
|
||||||
|
try (
|
||||||
|
InputStream inputStream = classPathResource.getInputStream();
|
||||||
|
InputStreamReader streamReader = new InputStreamReader(inputStream, "utf-8");
|
||||||
|
BufferedReader reader = new BufferedReader(streamReader);
|
||||||
|
PrintWriter out = response.getWriter()) {
|
||||||
|
Properties languageDict = KoUtil.getLanguageDict(language);
|
||||||
|
String context = request.getContextPath();
|
||||||
|
if (StringUtils.hasText(Context.getConfig().getContextPath())) {
|
||||||
|
context = Context.getConfig().getContextPath();
|
||||||
|
}
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
String line = "";
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
line = formatStaticResource(line,context,kotoken);
|
||||||
|
line = formatLanguageDesc(line, languageDict);
|
||||||
|
stringBuilder.append(line + "\n");
|
||||||
|
}
|
||||||
|
line = stringBuilder.toString();
|
||||||
|
out.write(line);
|
||||||
|
out.flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatStaticResource(String line,String context,String kotoken) {
|
||||||
|
boolean staticTokenVisit = false;
|
||||||
|
if (StringUtils.hasText(kotoken)) {
|
||||||
|
staticTokenVisit = true;
|
||||||
|
}
|
||||||
|
if (line.indexOf(KoConstant.globalThreshold) > -1) {
|
||||||
|
line = line.replace(KoConstant.globalThreshold, Context.getConfig().getThreshold() + "");
|
||||||
|
} else if (line.indexOf(KoConstant.globalNeedLogin) > -1) {
|
||||||
|
line = line.replace(KoConstant.globalNeedLogin, Context.getConfig().getAuthEnable() + "");
|
||||||
|
} else if (line.indexOf(KoConstant.contextPath) > -1) {
|
||||||
|
line = line.replace(KoConstant.contextPath, context);
|
||||||
|
} else if (line.indexOf(KoConstant.exceptionTitleStyle) > -1) {
|
||||||
|
line = line.replace(KoConstant.exceptionTitleStyle, Context.getConfig().getExceptionEnable() == true ? "" : "display:none;");
|
||||||
|
} else if (line.indexOf("UIKitCss") > -1) {
|
||||||
|
line = line.replace("UIKitCss", uiKitCssText);
|
||||||
|
} else if (line.indexOf("UIKitJs") > -1) {
|
||||||
|
line = line.replace("UIKitJs", uiKitJsText);
|
||||||
|
} else if (line.indexOf("MetricFlowJs") > -1) {
|
||||||
|
line = line.replace("MetricFlowJs", metricFlowJsText);
|
||||||
|
} else if (line.indexOf("jQueryJs") > -1) {
|
||||||
|
line = line.replace("jQueryJs", jQueryJsText);
|
||||||
|
} else if (line.indexOf("uiKitIconsJs") > -1) {
|
||||||
|
line = line.replace("uiKitIconsJs", uiKitIconsJs);
|
||||||
|
} else if (line.indexOf("staticTokenVisitValue") > -1) {
|
||||||
|
line = line.replace("staticTokenVisitValue", staticTokenVisit + "");
|
||||||
|
} else if (line.indexOf("staticTokenValue") > -1) {
|
||||||
|
line = line.replace("staticTokenValue", "'" + kotoken + "'");
|
||||||
|
} else if (line.indexOf("KoTimeUtil") > -1) {
|
||||||
|
line = line.replace("KoTimeUtil", KoTimeUtil);
|
||||||
|
} else if (line.indexOf("koTimeVersionValue") > -1) {
|
||||||
|
line = line.replace("koTimeVersionValue", "'" + KoUtil.getVerssion()+ "'");
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatLanguageDesc(String line, Properties languageDict) {
|
||||||
|
String languageKey = getLanguageKey(line);
|
||||||
|
if (languageKey != null) {
|
||||||
|
String key = languageKey.replaceAll("\\{|\\}", "");
|
||||||
|
String value = languageDict.getProperty(key);
|
||||||
|
line = line.replace(languageKey, value);
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLanguageKey(String line) {
|
||||||
|
Matcher m = pattern.matcher(line);
|
||||||
|
String key = null;
|
||||||
|
if (m.find()) {
|
||||||
|
key = m.group(0);
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getResourceText(String fileName) {
|
||||||
|
ClassPathResource classPathResource = new ClassPathResource(fileName);
|
||||||
|
try (InputStream inputStream = classPathResource.getInputStream();
|
||||||
|
InputStreamReader streamReader = new InputStreamReader(inputStream, "utf-8");
|
||||||
|
BufferedReader reader = new BufferedReader(streamReader)) {
|
||||||
|
String line = "";
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
stringBuilder.append(line + "\n");
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -2,24 +2,17 @@ package cn.langpy.kotime.controller;
|
|||||||
|
|
||||||
import cn.langpy.kotime.annotation.Auth;
|
import cn.langpy.kotime.annotation.Auth;
|
||||||
import cn.langpy.kotime.config.DefaultConfig;
|
import cn.langpy.kotime.config.DefaultConfig;
|
||||||
import cn.langpy.kotime.constant.KoConstant;
|
|
||||||
import cn.langpy.kotime.model.*;
|
import cn.langpy.kotime.model.*;
|
||||||
import cn.langpy.kotime.service.ClassService;
|
import cn.langpy.kotime.service.ClassService;
|
||||||
import cn.langpy.kotime.service.GraphService;
|
import cn.langpy.kotime.service.GraphService;
|
||||||
import cn.langpy.kotime.service.SysUsageService;
|
import cn.langpy.kotime.service.SysUsageService;
|
||||||
import cn.langpy.kotime.service.ThreadUsageService;
|
import cn.langpy.kotime.service.ThreadUsageService;
|
||||||
import cn.langpy.kotime.util.Context;
|
import cn.langpy.kotime.util.Context;
|
||||||
import cn.langpy.kotime.util.InvalidAuthInfoException;
|
|
||||||
import cn.langpy.kotime.util.KoUtil;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.core.io.ClassPathResource;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -33,132 +26,7 @@ import static cn.langpy.kotime.model.ThreadInfo.COMPARATOR;
|
|||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/koTime")
|
@RequestMapping("/koTime")
|
||||||
public class KoTimeController {
|
public class KoTimeController {
|
||||||
@Value("${ko-time.user-name:}")
|
|
||||||
private String userName;
|
|
||||||
@Value("${ko-time.password:}")
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(KoTimeController.class.toString());
|
private static Logger log = Logger.getLogger(KoTimeController.class.toString());
|
||||||
private final String uiKitCssText = getResourceText("kostatic/uikit.min.css");
|
|
||||||
private final String uiKitJsText = getResourceText("kostatic/uikit.min.js");
|
|
||||||
private final String metricFlowJsText = getResourceText("kostatic/Metricflow.js");
|
|
||||||
private final String jQueryJsText = getResourceText("kostatic/JQuery.min.js");
|
|
||||||
private final String uiKitIconsJs = getResourceText("kostatic/uikit-icons.js");
|
|
||||||
|
|
||||||
@PostMapping("/login")
|
|
||||||
@ResponseBody
|
|
||||||
public Map login(@RequestBody UserInfo userInfo) {
|
|
||||||
if (null == userInfo || !StringUtils.hasText(userInfo.getUserName()) || !StringUtils.hasText(userInfo.getPassword())) {
|
|
||||||
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())) {
|
|
||||||
String token = KoUtil.login(userInfo.getUserName());
|
|
||||||
map.put("state", 1);
|
|
||||||
map.put("token", token);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
map.put("state", 0);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/isLogin")
|
|
||||||
@ResponseBody
|
|
||||||
public Map isLogin(String kotoken) {
|
|
||||||
Map map = new HashMap();
|
|
||||||
map.put("state", 1);
|
|
||||||
boolean checkLogin = false;
|
|
||||||
if (StringUtils.hasText(kotoken)) {
|
|
||||||
if (kotoken.equals(Context.getConfig().getStaticToken())) {
|
|
||||||
checkLogin = true;
|
|
||||||
} else {
|
|
||||||
checkLogin = KoUtil.isLogin(kotoken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
map.put("isLogin", checkLogin ? 1 : 0);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public void index(String kotoken, String test,String charset, String language,HttpServletResponse response, HttpServletRequest request) {
|
|
||||||
if (!Context.getConfig().getEnable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (null != test) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
boolean staticTokenVisit = false;
|
|
||||||
if (StringUtils.hasText(kotoken)) {
|
|
||||||
staticTokenVisit = true;
|
|
||||||
}
|
|
||||||
if (!StringUtils.hasText(charset)) {
|
|
||||||
charset = "utf-8";
|
|
||||||
}
|
|
||||||
response.setContentType("text/html;charset="+charset);
|
|
||||||
ClassPathResource classPathResource = new ClassPathResource(KoConstant.getViewName(language));
|
|
||||||
try (
|
|
||||||
InputStream inputStream = classPathResource.getInputStream();
|
|
||||||
InputStreamReader streamReader = new InputStreamReader(inputStream, "utf-8");
|
|
||||||
BufferedReader reader = new BufferedReader(streamReader);
|
|
||||||
PrintWriter out = response.getWriter()) {
|
|
||||||
|
|
||||||
String context = request.getContextPath();
|
|
||||||
if (StringUtils.hasText(Context.getConfig().getContextPath())) {
|
|
||||||
context = Context.getConfig().getContextPath();
|
|
||||||
}
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
String line = "";
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
if (line.indexOf(KoConstant.globalThreshold) > -1) {
|
|
||||||
line = line.replace(KoConstant.globalThreshold, Context.getConfig().getThreshold() + "");
|
|
||||||
} else if (line.indexOf(KoConstant.globalNeedLogin) > -1) {
|
|
||||||
line = line.replace(KoConstant.globalNeedLogin, Context.getConfig().getAuthEnable() + "");
|
|
||||||
} else if (line.indexOf(KoConstant.contextPath) > -1) {
|
|
||||||
line = line.replace(KoConstant.contextPath, context);
|
|
||||||
} else if (line.indexOf(KoConstant.exceptionTitleStyle) > -1) {
|
|
||||||
line = line.replace(KoConstant.exceptionTitleStyle, Context.getConfig().getExceptionEnable() == true ? "" : "display:none;");
|
|
||||||
} else if (line.indexOf("UIKitCss") > -1) {
|
|
||||||
line = line.replace("UIKitCss", uiKitCssText);
|
|
||||||
} else if (line.indexOf("UIKitJs") > -1) {
|
|
||||||
line = line.replace("UIKitJs", uiKitJsText);
|
|
||||||
} else if (line.indexOf("MetricFlowJs") > -1) {
|
|
||||||
line = line.replace("MetricFlowJs", metricFlowJsText);
|
|
||||||
} else if (line.indexOf("jQueryJs") > -1) {
|
|
||||||
line = line.replace("jQueryJs", jQueryJsText);
|
|
||||||
} else if (line.indexOf("uiKitIconsJs") > -1) {
|
|
||||||
line = line.replace("uiKitIconsJs", uiKitIconsJs);
|
|
||||||
} else if (line.indexOf("staticTokenVisitValue") > -1) {
|
|
||||||
line = line.replace("staticTokenVisitValue", staticTokenVisit + "");
|
|
||||||
} else if (line.indexOf("staticTokenValue") > -1) {
|
|
||||||
line = line.replace("staticTokenValue", "'" + kotoken + "'");
|
|
||||||
}
|
|
||||||
stringBuilder.append(line + "\n");
|
|
||||||
}
|
|
||||||
line = stringBuilder.toString();
|
|
||||||
out.write(line);
|
|
||||||
out.flush();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getResourceText(String fileName) {
|
|
||||||
ClassPathResource classPathResource = new ClassPathResource(fileName);
|
|
||||||
try (InputStream inputStream = classPathResource.getInputStream();
|
|
||||||
InputStreamReader streamReader = new InputStreamReader(inputStream, "utf-8");
|
|
||||||
BufferedReader reader = new BufferedReader(streamReader)) {
|
|
||||||
String line = "";
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
stringBuilder.append(line + "\n");
|
|
||||||
}
|
|
||||||
return stringBuilder.toString();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/getConfig")
|
@GetMapping("/getConfig")
|
||||||
|
|||||||
@ -5,14 +5,21 @@ import cn.langpy.kotime.model.InvokedInfo;
|
|||||||
import cn.langpy.kotime.model.MethodNode;
|
import cn.langpy.kotime.model.MethodNode;
|
||||||
import cn.langpy.kotime.service.InvokedQueue;
|
import cn.langpy.kotime.service.InvokedQueue;
|
||||||
import cn.langpy.kotime.service.MethodNodeService;
|
import cn.langpy.kotime.service.MethodNodeService;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class KoUtil {
|
public class KoUtil {
|
||||||
|
private static Logger log = Logger.getLogger(KoUtil.class.toString());
|
||||||
|
|
||||||
private final static String koTimeSecret = UUID.randomUUID().toString().replace("-", "");
|
private final static String koTimeSecret = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
|
||||||
private final static List<Integer> choices = randomSecretIndexs();
|
private final static List<Integer> choices = randomSecretIndexs();
|
||||||
@ -215,5 +222,47 @@ public class KoUtil {
|
|||||||
return Arrays.stream(split1).collect(Collectors.toList());
|
return Arrays.stream(split1).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Properties getLanguageDict(String language) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
if (!StringUtils.hasText(language)) {
|
||||||
|
language = Context.getConfig().getLanguage();
|
||||||
|
}
|
||||||
|
ClassPathResource classPathResource = new ClassPathResource("kostatic/dict/"+language+".properties");
|
||||||
|
try (
|
||||||
|
InputStream inputStream = classPathResource.getInputStream();
|
||||||
|
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)
|
||||||
|
) {
|
||||||
|
properties.load(inputStreamReader);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
log.severe("kotime=>"+Context.getConfig().getLanguage()+".properties requires utf-8.");
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (FileNotFoundException e){
|
||||||
|
log.warning("kotime=>No "+Context.getConfig().getLanguage()+".properties found so that you can not use language properties to set.");
|
||||||
|
}catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getVerssion() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
ClassPathResource classPathResource = new ClassPathResource("koapp.properties");
|
||||||
|
try (
|
||||||
|
InputStream inputStream = classPathResource.getInputStream();
|
||||||
|
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)
|
||||||
|
) {
|
||||||
|
properties.load(inputStreamReader);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
log.severe("kotime=>koapp.properties requires utf-8.");
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (FileNotFoundException e){
|
||||||
|
log.warning("kotime=>No koapp.properties found.");
|
||||||
|
}catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return properties.getProperty("ko-time.version");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/main/resources/koapp.properties
Normal file
1
src/main/resources/koapp.properties
Normal file
@ -0,0 +1 @@
|
|||||||
|
ko-time.version=2.4.5
|
||||||
103
src/main/resources/kostatic/dict/chinese.properties
Normal file
103
src/main/resources/kostatic/dict/chinese.properties
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
kotime-title=KoTime调用链路追踪
|
||||||
|
kotime-confirm=确定
|
||||||
|
kotime-refresh=刷新数据
|
||||||
|
tab.summary=总览
|
||||||
|
tab.interface=接口列表
|
||||||
|
tab.exception=异常列表
|
||||||
|
tab.thread=线程列表
|
||||||
|
tab.hotupdate=热更新
|
||||||
|
tab.configuration=配置
|
||||||
|
tab.support=技术支持
|
||||||
|
|
||||||
|
tab.summary.interface-metric=接口统计
|
||||||
|
tab.summary.response-metric=响应统计
|
||||||
|
tab.summary.sysusage-metric=系统使用情况
|
||||||
|
tab.summary.bottom-normal-tip=接口根据调用情况统计,未调用的接口无法被统计到,请先调用接口
|
||||||
|
tab.summary.bottom-close-tip=方法调用监测已关闭,数据将不会更新,需要开启请到配置面板
|
||||||
|
|
||||||
|
tab.summary.interface-metric.total-num=接口数
|
||||||
|
tab.summary.interface-metric.delay-num=延迟响应数
|
||||||
|
tab.summary.interface-metric.normal-num=正常响应数
|
||||||
|
|
||||||
|
tab.summary.response-metric.avg-num=平均响应(ms)
|
||||||
|
tab.summary.response-metric.max-num=最大响应(ms)
|
||||||
|
tab.summary.response-metric.min-num=最小响应(ms)
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.cpu-usage=CPU使用率
|
||||||
|
tab.summary.sysusage-metric.heap-memory=堆内存
|
||||||
|
tab.summary.sysusage-metric.physical-memory=物理内存
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.cpu-usage.user-usage=用户使用率
|
||||||
|
tab.summary.sysusage-metric.cpu-usage.sys-usage=系统使用率
|
||||||
|
tab.summary.sysusage-metric.cpu-usage.io-waiting=IO 等待率
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.heap-memory.init=初始值
|
||||||
|
tab.summary.sysusage-metric.heap-memory.max=最大值
|
||||||
|
tab.summary.sysusage-metric.heap-memory.used=已使用
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.physical-memory.total=总物理内存
|
||||||
|
tab.summary.sysusage-metric.physical-memory.used=已使用内存
|
||||||
|
tab.summary.sysusage-metric.physical-memory.current-used=此程序占用
|
||||||
|
|
||||||
|
|
||||||
|
tab.interface.search-tip=搜索方法名或者类名...
|
||||||
|
tab.interface.interface-list.avg-tip=平均响应
|
||||||
|
tab.interface.interface-list.show-metric.type=类型
|
||||||
|
tab.interface.interface-list.show-metric.avg=平均耗时
|
||||||
|
tab.interface.interface-list.show-metric.max=最大耗时
|
||||||
|
tab.interface.interface-list.show-metric.min=最小耗时
|
||||||
|
tab.interface.interface-list.show-metric.exception-num=异常数目
|
||||||
|
tab.interface.interface-list.show-metric.exception-unit=个
|
||||||
|
tab.interface.interface-list.show-metric.param-analyse=入参组合分析
|
||||||
|
|
||||||
|
|
||||||
|
tab.exception.exception-list.show-metric.class=异常类
|
||||||
|
tab.exception.exception-list.show-metric.method=异常方法
|
||||||
|
tab.exception.exception-list.show-metric.line=异常行
|
||||||
|
tab.exception.exception-list.show-metric.message=异常消息
|
||||||
|
|
||||||
|
tab.thread.thread-metric=线程统计
|
||||||
|
tab.thread.thread-list=线程列表
|
||||||
|
|
||||||
|
tab.thread.thread-list.cpu-usage=CPU使用率
|
||||||
|
|
||||||
|
tab.thread.thread-metric.all=ALL
|
||||||
|
tab.thread.thread-metric.runnable=RUNNABLE
|
||||||
|
tab.thread.thread-metric.blocked=BLOCKED
|
||||||
|
tab.thread.thread-metric.waiting=WAITING
|
||||||
|
tab.thread.thread-metric.time-waiting=TIME_WAITING
|
||||||
|
|
||||||
|
tab.hotupdate.class-file-input-tip=更新的类文件:编译过的.class文件
|
||||||
|
tab.hotupdate.class-file-null-tip=类文件不能为空
|
||||||
|
tab.hotupdate.class-name-input-tip=更新的类全名:com.xx.xx.TestService
|
||||||
|
tab.hotupdate.class-name-null-tip=类名不能为空
|
||||||
|
tab.hotupdate.confirm-name=更新
|
||||||
|
tab.hotupdate.change-ok-tip=更新成功
|
||||||
|
tab.hotupdate.change-fail-tip=更新失败
|
||||||
|
|
||||||
|
tab.configuration.kotime-config=KoTime配置
|
||||||
|
tab.configuration.dynamic-config=dynamic.properties配置
|
||||||
|
|
||||||
|
tab.configuration.kotime-config.enable-kotime-tip=开启KoTime
|
||||||
|
tab.configuration.kotime-config.enable-exception-tip=开启异常检测
|
||||||
|
tab.configuration.kotime-config.enable-console-tip=开启控制台日志
|
||||||
|
tab.configuration.kotime-config.enable-email-tip=开启邮件通知
|
||||||
|
tab.configuration.kotime-config.select-language-tip=语言选择
|
||||||
|
tab.configuration.kotime-config.select-language-chinese=中文
|
||||||
|
tab.configuration.kotime-config.select-language-english=英文
|
||||||
|
tab.configuration.kotime-config.threshold-tip=方法运行时间阈值
|
||||||
|
tab.configuration.kotime-config.threshold-confirm=确认
|
||||||
|
tab.configuration.kotime-config.clear-data-tip=清空链路数据
|
||||||
|
tab.configuration.kotime-config.clear-data-confirm=确认
|
||||||
|
tab.configuration.kotime-config.change-ok-tip=设置成功
|
||||||
|
tab.configuration.kotime-config.change-fail-tip=更新失败
|
||||||
|
tab.configuration.bottom-tip=变更配置以后请重新刷新页面
|
||||||
|
|
||||||
|
tab.configuration.dynamic-config.confirm-name=更新
|
||||||
|
tab.configuration.dynamic-config.change-ok-tip=更新成功
|
||||||
|
tab.configuration.dynamic-config.change-fail-tip=更新失败,请正确编写配置!
|
||||||
|
|
||||||
|
tab.support.version-tip=点击查看版本发布信息
|
||||||
|
tab.support.support-tip=技术支持
|
||||||
|
tab.support.pro-tip=升级专业版
|
||||||
|
tab.support.plugin-tip=本地化插件
|
||||||
103
src/main/resources/kostatic/dict/english.properties
Normal file
103
src/main/resources/kostatic/dict/english.properties
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
kotime-title=KoTime
|
||||||
|
kotime-confirm=OK
|
||||||
|
kotime-refresh=refresh
|
||||||
|
tab.summary=Summary
|
||||||
|
tab.interface=Interfaces
|
||||||
|
tab.exception=Exceptions
|
||||||
|
tab.thread=Threads
|
||||||
|
tab.hotupdate=Hot Update
|
||||||
|
tab.configuration=Configurations
|
||||||
|
tab.support=Tech Support
|
||||||
|
|
||||||
|
tab.summary.interface-metric=Number of Interface
|
||||||
|
tab.summary.response-metric=Response Time
|
||||||
|
tab.summary.sysusage-metric=System Usage
|
||||||
|
tab.summary.bottom-normal-tip=Please call apis before visiting this page!
|
||||||
|
tab.summary.bottom-close-tip=KoTime switch was closed!
|
||||||
|
|
||||||
|
tab.summary.interface-metric.total-num=Total
|
||||||
|
tab.summary.interface-metric.delay-num=Delayed
|
||||||
|
tab.summary.interface-metric.normal-num=Normal
|
||||||
|
|
||||||
|
tab.summary.response-metric.avg-num=Avg(ms)
|
||||||
|
tab.summary.response-metric.max-num=Max(ms)
|
||||||
|
tab.summary.response-metric.min-num=Min(ms)
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.cpu-usage=CPU Usage
|
||||||
|
tab.summary.sysusage-metric.heap-memory=Heap Memory
|
||||||
|
tab.summary.sysusage-metric.physical-memory=Physical Memory
|
||||||
|
|
||||||
|
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.io-waiting=IO Wait Rate
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.heap-memory.init=Init
|
||||||
|
tab.summary.sysusage-metric.heap-memory.max=Max
|
||||||
|
tab.summary.sysusage-metric.heap-memory.used=Used
|
||||||
|
|
||||||
|
tab.summary.sysusage-metric.physical-memory.total=Total
|
||||||
|
tab.summary.sysusage-metric.physical-memory.used=Used
|
||||||
|
tab.summary.sysusage-metric.physical-memory.current-used=ThisUsed
|
||||||
|
|
||||||
|
|
||||||
|
tab.interface.search-tip=search method name or class name...
|
||||||
|
tab.interface.interface-list.avg-tip=avg
|
||||||
|
tab.interface.interface-list.show-metric.type=type
|
||||||
|
tab.interface.interface-list.show-metric.avg=avg time
|
||||||
|
tab.interface.interface-list.show-metric.max=max time
|
||||||
|
tab.interface.interface-list.show-metric.min=min time
|
||||||
|
tab.interface.interface-list.show-metric.exception-num=number of exception
|
||||||
|
tab.interface.interface-list.show-metric.exception-unit=
|
||||||
|
tab.interface.interface-list.show-metric.param-analyse=Combination of parameters
|
||||||
|
|
||||||
|
|
||||||
|
tab.exception.exception-list.show-metric.class=Class
|
||||||
|
tab.exception.exception-list.show-metric.method=Method
|
||||||
|
tab.exception.exception-list.show-metric.line=Line
|
||||||
|
tab.exception.exception-list.show-metric.message=exception message
|
||||||
|
|
||||||
|
tab.thread.thread-metric=Number of Thread
|
||||||
|
tab.thread.thread-list=Thread List
|
||||||
|
|
||||||
|
tab.thread.thread-list.cpu-usage=CPU Usage
|
||||||
|
|
||||||
|
tab.thread.thread-metric.all=ALL
|
||||||
|
tab.thread.thread-metric.runnable=RUNNABLE
|
||||||
|
tab.thread.thread-metric.blocked=BLOCKED
|
||||||
|
tab.thread.thread-metric.waiting=WAITING
|
||||||
|
tab.thread.thread-metric.time-waiting=TIME_WAITING
|
||||||
|
|
||||||
|
tab.hotupdate.class-file-input-tip=class file needed to update:compiled class file
|
||||||
|
tab.hotupdate.class-file-null-tip=Null file
|
||||||
|
tab.hotupdate.class-name-input-tip=class name needed to update :com.xx.xx.TestService
|
||||||
|
tab.hotupdate.class-name-null-tip=Null class name
|
||||||
|
tab.hotupdate.confirm-name=Update
|
||||||
|
tab.hotupdate.change-ok-tip=OK
|
||||||
|
tab.hotupdate.change-fail-tip=FAIL
|
||||||
|
|
||||||
|
tab.configuration.kotime-config=KoTime Configure
|
||||||
|
tab.configuration.dynamic-config=dynamic.properties Configure
|
||||||
|
|
||||||
|
tab.configuration.kotime-config.enable-kotime-tip=KoTime switch
|
||||||
|
tab.configuration.kotime-config.enable-exception-tip=exception switch
|
||||||
|
tab.configuration.kotime-config.enable-console-tip=console log switch
|
||||||
|
tab.configuration.kotime-config.enable-email-tip=email switch
|
||||||
|
tab.configuration.kotime-config.select-language-tip=language switch
|
||||||
|
tab.configuration.kotime-config.select-language-chinese=Chinese
|
||||||
|
tab.configuration.kotime-config.select-language-english=English
|
||||||
|
tab.configuration.kotime-config.threshold-tip=time threshold
|
||||||
|
tab.configuration.kotime-config.threshold-confirm=OK
|
||||||
|
tab.configuration.kotime-config.clear-data-tip=clear data
|
||||||
|
tab.configuration.kotime-config.clear-data-confirm=OK
|
||||||
|
tab.configuration.kotime-config.change-ok-tip=OK
|
||||||
|
tab.configuration.kotime-config.change-fail-tip=FAIL
|
||||||
|
tab.configuration.bottom-tip=Please refresh this page after updating configurations
|
||||||
|
|
||||||
|
tab.configuration.dynamic-config.confirm-name=Update
|
||||||
|
tab.configuration.dynamic-config.change-ok-tip=OK
|
||||||
|
tab.configuration.dynamic-config.change-fail-tip=FAIL!
|
||||||
|
|
||||||
|
tab.support.version-tip=show versions
|
||||||
|
tab.support.support-tip=Tech Support
|
||||||
|
tab.support.pro-tip=KoTime Pro
|
||||||
|
tab.support.plugin-tip=Local Plugin
|
||||||
64
src/main/resources/kostatic/util.js
Normal file
64
src/main/resources/kostatic/util.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
function getSize(size) {
|
||||||
|
let sizes = [' Bytes', ' KB', ' MB', ' GB',
|
||||||
|
' TB', ' PB', ' EB', ' ZB', ' YB'];
|
||||||
|
|
||||||
|
for (let i = 1; i < sizes.length; i++) {
|
||||||
|
if (size < Math.pow(1024, i))
|
||||||
|
return (Math.round((size / Math.pow(1024, i - 1)) * 100) / 100) + sizes[i - 1];
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDom(id){
|
||||||
|
return document.getElementById(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
function post(url,data,successfun,errorFun) {
|
||||||
|
fetch(url, {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
}).then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
successfun(json);
|
||||||
|
}).catch(e => {
|
||||||
|
if (errorFun) {
|
||||||
|
errorFun(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function postFormData(url,data,successfun,errorFun) {
|
||||||
|
fetch(url, {
|
||||||
|
method: 'post',
|
||||||
|
body: data
|
||||||
|
}).then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
successfun(json);
|
||||||
|
}).catch(e => {
|
||||||
|
if (errorFun) {
|
||||||
|
errorFun(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(url,fun) {
|
||||||
|
fetch(url).then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
fun(json)
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function noticeSuccess(message){
|
||||||
|
UIkit.notification.closeAll();
|
||||||
|
UIkit.notification("<font color='green'>"+message+"</font>", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function noticeError(message){
|
||||||
|
UIkit.notification.closeAll();
|
||||||
|
UIkit.notification("<font color='red'>"+message+"</font>", {});
|
||||||
|
}
|
||||||
@ -1,992 +0,0 @@
|
|||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>KoTime</title>
|
|
||||||
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/css/uikit.min.css"/>-->
|
|
||||||
<!-- UIkit JS -->
|
|
||||||
<!-- <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/js/uikit.min.js"></script>-->
|
|
||||||
<!-- <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.2/dist/js/uikit-icons.min.js"></script>-->
|
|
||||||
<style>
|
|
||||||
UIKitCss
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
UIKitJs;
|
|
||||||
uiKitIconsJs;
|
|
||||||
MetricFlowJs;
|
|
||||||
jQueryJs;
|
|
||||||
var graph;
|
|
||||||
var d = 180;
|
|
||||||
var globalThreshold = globalThresholdValue;
|
|
||||||
var globalNeedLogin = globalNeedLoginValue;
|
|
||||||
var staticTokenVisit = staticTokenVisitValue;
|
|
||||||
var staticToken = staticTokenValue;
|
|
||||||
var globalToken = staticTokenVisit?staticToken:sessionStorage.getItem("kotimeToken");
|
|
||||||
var globalToken = sessionStorage.getItem("kotimeToken");
|
|
||||||
let globalIsLogin = false;
|
|
||||||
|
|
||||||
function concatToken(url) {
|
|
||||||
if (globalNeedLogin) {
|
|
||||||
if (url.indexOf('?')>-1) {
|
|
||||||
url += '&kotoken='+globalToken;
|
|
||||||
}else {
|
|
||||||
url += '?kotoken='+globalToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
|
|
||||||
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(concatToken('contextPath/koTime/getParamGraph'+"?methodId="+clickNodeId.replace('node','')), 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(concatToken('contextPath/koTime/getTree?methodName=' + name), 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(concatToken('contextPath/koTime/getMethodsByExceptionId?exceptionId=' + id+'&message='+message), 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'>Error username or password</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'>Logined</font>",{});
|
|
||||||
UIkit.notification.closeAll()
|
|
||||||
sessionStorage.setItem("kotimeToken", re["token"]);
|
|
||||||
location.reload();
|
|
||||||
}else {
|
|
||||||
UIkit.notification("<font color='red'>Error username or password</font>",{});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error:function (re) {
|
|
||||||
console.log(re)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function searchTip(e){
|
|
||||||
let question = $('#searchText').val()
|
|
||||||
$.get(concatToken('contextPath/koTime/getApiTips?question='+question), function (data) {
|
|
||||||
$("#condidates").html("")
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
let name = data[i];
|
|
||||||
$("#condidates").append('<option value="'+name+'"/>');
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function searchApis(e) {
|
|
||||||
if (e.keyCode == 13) {
|
|
||||||
let question = $('#searchText').val()
|
|
||||||
$.get(concatToken('contextPath/koTime/getApis?question='+question), function (data) {
|
|
||||||
let element = document.getElementById('apiList');
|
|
||||||
html = '';
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
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('"+apiId+"')\" 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;text-transform: lowercase' class=\"uk-label uk-label-"+color+"\">avg "+avgRunTime+" ms</span></li>";
|
|
||||||
}else{
|
|
||||||
html += "<li onclick=\"showMethods('"+apiId+"')\" 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;text-transform: lowercase' class=\"uk-label uk-label-"+color+"\">avg "+avgRunTime+" ms</span></li>";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
element.innerHTML = html;
|
|
||||||
});
|
|
||||||
$('#searchText').val('');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateClass(){
|
|
||||||
// document.querySelector("#classForm").submit();
|
|
||||||
var formData = new FormData();
|
|
||||||
var file = document.querySelector('#classFile').files[0];
|
|
||||||
if (file==null || file==undefined) {
|
|
||||||
UIkit.notification("<font color='red'>Null file</font>",{});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var className = document.querySelector("#className").value
|
|
||||||
if (className==null || className==undefined || className.length<2) {
|
|
||||||
UIkit.notification("<font color='red'>Null class name</font>",{});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
formData.append('classFile', file);
|
|
||||||
formData.append('className', className );
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: concatToken('contextPath/koTime/updateClass'),
|
|
||||||
type: 'POST',
|
|
||||||
cache: false,
|
|
||||||
data: formData,
|
|
||||||
processData: false,
|
|
||||||
contentType: false,
|
|
||||||
dataType: "json",
|
|
||||||
success: function (res) {
|
|
||||||
if (res['state']==1) {
|
|
||||||
UIkit.notification.closeAll();
|
|
||||||
UIkit.notification("<font color='green'>Success</font>",{});
|
|
||||||
}else {
|
|
||||||
UIkit.notification.closeAll();
|
|
||||||
UIkit.notification("<font color='red'>"+res['message']+"</font>",{});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (XmlHttpRequest, textStatus, errorThrown) {
|
|
||||||
UIkit.notification.closeAll();
|
|
||||||
UIkit.notification("<font color='red'>Fail</font>",{});
|
|
||||||
location.reload();
|
|
||||||
},
|
|
||||||
complete: function () {}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateDynamicProperties(){
|
|
||||||
let propertiesDom = document.querySelector("#dynamicText");
|
|
||||||
let propertiesText = propertiesDom.value;
|
|
||||||
if (propertiesText && propertiesText.indexOf("=")>0) {
|
|
||||||
$.ajax({
|
|
||||||
type:'POST',
|
|
||||||
url:concatToken('contextPath/koTime/updateDynamicProperties'),
|
|
||||||
data:JSON.stringify({
|
|
||||||
text:propertiesText
|
|
||||||
}),
|
|
||||||
dataType:'json',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
success:function (re) {
|
|
||||||
UIkit.notification.closeAll();
|
|
||||||
UIkit.notification("<font color='green'>更新成功</font>",{});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}else {
|
|
||||||
UIkit.notification.closeAll();
|
|
||||||
UIkit.notification("<font color='red'>更新失败,请正确编写配置!</font>",{});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadDynamicProperties() {
|
|
||||||
$.get(concatToken('contextPath/koTime/getDynamicProperties'), function (data) {
|
|
||||||
let text = data['data'];
|
|
||||||
document.querySelector("#dynamicText").value = text;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadLatestVersion(){
|
|
||||||
/*get the latest version so that you can update kotime immediately*/
|
|
||||||
$.ajax({
|
|
||||||
url: 'http://www.kotime.cn/common/latestVersion?version=2.3.7',
|
|
||||||
type: 'GET',
|
|
||||||
cache: false,
|
|
||||||
dataType: "json",
|
|
||||||
async: true,
|
|
||||||
success: function (res) {
|
|
||||||
if (res['state']==1) {
|
|
||||||
document.querySelector("#version-notice").innerHTML=res['content']['versionNo']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (XmlHttpRequest, textStatus, errorThrown) {
|
|
||||||
|
|
||||||
},
|
|
||||||
complete: function () {}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function loadCpuInfo() {
|
|
||||||
$.get(concatToken('contextPath/koTime/getCpuInfo'), function (data) {
|
|
||||||
let systemLoad = data['systemLoad']*100;
|
|
||||||
let userRate = data['userRate']*100;
|
|
||||||
let sysRate = data['sysRate']*100;
|
|
||||||
let logicalNum = data['logicalNum'];
|
|
||||||
let waitRate = data['waitRate']*100;
|
|
||||||
|
|
||||||
var systemLoadDom = document.querySelector("#systemLoad");
|
|
||||||
if (systemLoad>50) {
|
|
||||||
systemLoadDom.style.color='#cc0c0c';
|
|
||||||
}else {
|
|
||||||
systemLoadDom.style.color='#29da93';
|
|
||||||
};
|
|
||||||
systemLoadDom.innerHTML = `${systemLoad.toFixed(2)}%`;
|
|
||||||
document.querySelector("#cpuSysRate").innerHTML = `${sysRate.toFixed(2)}%`;
|
|
||||||
document.querySelector("#cpuUserRate").innerHTML = `${userRate.toFixed(2)}%`;
|
|
||||||
document.querySelector("#cpuWaitRate").innerHTML = `${waitRate.toFixed(2)}%`;
|
|
||||||
document.querySelector("#cpuLogicalAmount").innerHTML = `CPU Usage(${logicalNum}):`;
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function loadHeapMemoryInfo() {
|
|
||||||
$.get(concatToken('contextPath/koTime/getHeapMemoryInfo'), function (data) {
|
|
||||||
let initValue = data['initValue']/1024/1024;
|
|
||||||
let maxValue = data['maxValue']/1024/1024;
|
|
||||||
let usedValue = data['usedValue']/1024/1024;
|
|
||||||
let usedRate = data['usedRate']*100;
|
|
||||||
var heapUsedRateDom = document.querySelector("#heapUsedRate");
|
|
||||||
if (usedRate>50) {
|
|
||||||
heapUsedRateDom.style.color='#cc0c0c';
|
|
||||||
}else {
|
|
||||||
heapUsedRateDom.style.color='#29da93';
|
|
||||||
};
|
|
||||||
document.querySelector("#heapInit").innerHTML = `${initValue.toFixed()}M`;
|
|
||||||
document.querySelector("#heapMax").innerHTML = `${maxValue.toFixed()}M`;
|
|
||||||
document.querySelector("#heapUsed").innerHTML = `${usedValue.toFixed()}M`;
|
|
||||||
heapUsedRateDom.innerHTML = `${usedRate.toFixed(2)}%`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function loadPhysicalMemoryInfo() {
|
|
||||||
$.get(concatToken('contextPath/koTime/getPhysicalMemoryInfo'), function (data) {
|
|
||||||
let initValue = data['initValue']/1024/1024;
|
|
||||||
let thisUsedValue = data['thisUsedValue']/1024/1024;
|
|
||||||
let usedValue = data['usedValue']/1024/1024;
|
|
||||||
let usedRate = data['usedRate']*100;
|
|
||||||
var physicalUsedRateDom = document.querySelector("#physicalUsedRate");
|
|
||||||
if (usedRate>50) {
|
|
||||||
physicalUsedRateDom.style.color='#cc0c0c';
|
|
||||||
}else {
|
|
||||||
physicalUsedRateDom.style.color='#29da93';
|
|
||||||
};
|
|
||||||
physicalUsedRateDom.innerHTML = `${usedRate.toFixed(2)}%`;
|
|
||||||
document.querySelector("#physicalAmount").innerHTML = `${initValue.toFixed()}M`;
|
|
||||||
document.querySelector("#physicalUsed").innerHTML = `${usedValue.toFixed()}M`;
|
|
||||||
document.querySelector("#thisUsed").innerHTML = `${thisUsedValue.toFixed()}M`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadConfig() {
|
|
||||||
$.get(concatToken('contextPath/koTime/getConfig'), function (data) {
|
|
||||||
let versionNoticeEnable = data['versionNotice'];
|
|
||||||
if (versionNoticeEnable) {
|
|
||||||
loadLatestVersion();
|
|
||||||
}
|
|
||||||
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?"We can see interfaces after invoking methods!":"KoTime switch was closed!";
|
|
||||||
|
|
||||||
|
|
||||||
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 mailEnable = data['mailEnable'];
|
|
||||||
let mailEnableDom = document.getElementById('mailEnable');
|
|
||||||
mailEnableDom.checked = mailEnable;
|
|
||||||
|
|
||||||
let language = data['language'];
|
|
||||||
$("#languageSwitch").val(language)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addConfigEvent() {
|
|
||||||
|
|
||||||
document.getElementById('kotimeEnable').onclick = function(){
|
|
||||||
$.ajax({type:'POST',url:concatToken('contextPath/koTime/updateConfig'),data:JSON.stringify({enable:document.getElementById('kotimeEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
UIkit.notification("<font color='green'>OK</font>",{});
|
|
||||||
};
|
|
||||||
|
|
||||||
document.getElementById('exceptionEnable').onclick = function(){
|
|
||||||
$.ajax({type:'POST',url:concatToken('contextPath/koTime/updateConfig'),data:JSON.stringify({exceptionEnable:document.getElementById('exceptionEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
UIkit.notification("<font color='green'>OK</font>",{});
|
|
||||||
};
|
|
||||||
|
|
||||||
document.getElementById('logEnable').onclick = function(){
|
|
||||||
$.ajax({type:'POST',url:concatToken('contextPath/koTime/updateConfig'),data:JSON.stringify({logEnable:document.getElementById('logEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
UIkit.notification("<font color='green'>OK</font>",{});
|
|
||||||
};
|
|
||||||
|
|
||||||
document.getElementById('mailEnable').onclick = function(){
|
|
||||||
$.ajax({type:'POST',url:concatToken('contextPath/koTime/updateConfig'),data:JSON.stringify({mailEnable:document.getElementById('mailEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
UIkit.notification("<font color='green'>OK</font>",{});
|
|
||||||
};
|
|
||||||
|
|
||||||
document.getElementById('languageSwitch').onchange = function(){
|
|
||||||
let selectedObj = document.getElementById('languageSwitch');
|
|
||||||
$.ajax({type:'POST',url:concatToken('contextPath/koTime/updateConfig'),data:JSON.stringify({language:selectedObj.options[selectedObj.selectedIndex].value}),dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
UIkit.notification("<font color='green'>OK</font>",{});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementById("timeThresholdYes").onclick = function(){
|
|
||||||
$.ajax({type:'POST',url:concatToken('contextPath/koTime/updateConfig'),data:JSON.stringify({threshold:document.getElementById('timeThreshold').value}),dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
UIkit.notification("<font color='green'>OK</font>",{});
|
|
||||||
};
|
|
||||||
|
|
||||||
document.getElementById("clearDataYes").onclick = function(){
|
|
||||||
$.ajax({type:'POST',url:'contextPath/koTime/clearData?kotoken='+globalToken,dataType:'json', headers: {'Content-Type': 'application/json' }});
|
|
||||||
UIkit.notification("<font color='green'>OK</font>",{});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadStatistic() {
|
|
||||||
$.get(concatToken('contextPath/koTime/getStatistic'), 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;
|
|
||||||
|
|
||||||
let avgRunTime = data['avgRunTime'];
|
|
||||||
let systemAvgRunTime = document.getElementById("systemAvgRunTime");
|
|
||||||
systemAvgRunTime.innerHTML=avgRunTime;
|
|
||||||
if (avgRunTime>globalThreshold) {
|
|
||||||
document.getElementById("systemAvgRunTime").style.color='#cc0c0c';
|
|
||||||
}else {
|
|
||||||
document.getElementById("systemAvgRunTime").style.color='#29da93';
|
|
||||||
};
|
|
||||||
|
|
||||||
let maxRunTime = data['maxRunTime'];
|
|
||||||
let systemMaxRunTime = document.getElementById("systemMaxRunTime");
|
|
||||||
systemMaxRunTime.innerHTML=maxRunTime;
|
|
||||||
if (maxRunTime>globalThreshold) {
|
|
||||||
document.getElementById("systemMaxRunTime").style.color='#cc0c0c';
|
|
||||||
}else {
|
|
||||||
document.getElementById("systemMaxRunTime").style.color='#29da93';
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
let minRunTime = data['minRunTime'];
|
|
||||||
let systemMinRunTime = document.getElementById("systemMinRunTime");
|
|
||||||
systemMinRunTime.innerHTML=minRunTime;
|
|
||||||
if (minRunTime>globalThreshold) {
|
|
||||||
document.getElementById("systemMinRunTime").style.color='#cc0c0c';
|
|
||||||
}else {
|
|
||||||
document.getElementById("systemMinRunTime").style.color='#29da93';
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadApis() {
|
|
||||||
let searchText = $("#searchText").val();
|
|
||||||
$.get(concatToken('contextPath/koTime/getApis?question='+searchText), function (data) {
|
|
||||||
let element = document.getElementById('apiList');
|
|
||||||
html = '';
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
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('"+apiId+"')\" 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;text-transform: lowercase' class=\"uk-label uk-label-"+color+"\">avg "+avgRunTime+" ms</span></li>";
|
|
||||||
}else{
|
|
||||||
html += "<li onclick=\"showMethods('"+apiId+"')\" 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;text-transform: lowercase' class=\"uk-label uk-label-"+color+"\">avg "+avgRunTime+" ms</span></li>";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
element.innerHTML = html;
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadExceptions() {
|
|
||||||
$.get(concatToken('contextPath/koTime/getExceptions'), 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;
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshData() {
|
|
||||||
$.get(concatToken('contextPath/koTime/isLogin'), function (data) {
|
|
||||||
globalIsLogin = data['isLogin']==1?true:false;
|
|
||||||
if (globalNeedLogin==true && globalIsLogin == false) {
|
|
||||||
UIkit.modal(document.getElementById("modal-login")).show();
|
|
||||||
return;
|
|
||||||
}else {
|
|
||||||
loadStatistic();
|
|
||||||
loadConfig();
|
|
||||||
addConfigEvent();
|
|
||||||
loadApis();
|
|
||||||
loadExceptions();
|
|
||||||
loadCpuInfo();
|
|
||||||
loadHeapMemoryInfo();
|
|
||||||
loadPhysicalMemoryInfo();
|
|
||||||
loadThreadsInfo();
|
|
||||||
loadDynamicProperties();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const cpuUsageColorMap = {
|
|
||||||
'RED': '#cc0c0c',
|
|
||||||
'YELLOW': '#f0ad4e',
|
|
||||||
'LIGHT_BLUE': '#5bc0de'
|
|
||||||
};
|
|
||||||
function getCpuUsageColor(usage) {
|
|
||||||
if (usage > 50) {
|
|
||||||
return cpuUsageColorMap['RED'];
|
|
||||||
} else if (usage >= 20 && usage <= 50) {
|
|
||||||
return cpuUsageColorMap['YELLOW'];
|
|
||||||
} else {
|
|
||||||
return cpuUsageColorMap['LIGHT_BLUE'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let threadMap = new Map();
|
|
||||||
function loadThreadsInfo(queryState) {
|
|
||||||
queryState = queryState || '';
|
|
||||||
$.get(concatToken('contextPath/koTime/getThreadsInfo?state='+queryState), function (data) {
|
|
||||||
let statistics = data['statistics'];
|
|
||||||
let all = statistics['all'];
|
|
||||||
let RUNNABLE = statistics['RUNNABLE'] || 0;
|
|
||||||
let BLOCKED = statistics['BLOCKED'] || 0;
|
|
||||||
let WAITING = statistics['WAITING'] || 0;
|
|
||||||
let TIMED_WAITING = statistics['TIMED_WAITING'] || 0;
|
|
||||||
|
|
||||||
document.querySelector("#threadNum").innerHTML = all;
|
|
||||||
document.querySelector("#runnableNum").innerHTML = RUNNABLE;
|
|
||||||
document.querySelector("#blockedNum").innerHTML = BLOCKED;
|
|
||||||
document.querySelector("#waitingNum").innerHTML = WAITING;
|
|
||||||
document.querySelector("#timedWaitingNum").innerHTML = TIMED_WAITING;
|
|
||||||
|
|
||||||
let element = document.getElementById('threadList');
|
|
||||||
let html = '';
|
|
||||||
let threads = data['threads'];
|
|
||||||
let colors = {
|
|
||||||
'RUNNABLE':'#32d296',
|
|
||||||
'BLOCKED':'#cc0c0c',
|
|
||||||
'WAITING':'#ad7070',
|
|
||||||
'TIMED_WAITING':'#ad7070'
|
|
||||||
}
|
|
||||||
for (let i = 0; i < threads.length; i++) {
|
|
||||||
let thread = threads[i];
|
|
||||||
let id = thread['id'];
|
|
||||||
let name = thread['name'];
|
|
||||||
let classType = thread['classType'];
|
|
||||||
let state = thread['state'];
|
|
||||||
let stacks = thread['stacks'];
|
|
||||||
let cpuUsage = thread['cpuUsage'];
|
|
||||||
let cpuUsageColor = getCpuUsageColor(cpuUsage);
|
|
||||||
threadMap[id+''] = stacks;
|
|
||||||
html+=`<li onclick="showThreadInfo('${id}')" style='color: #333;font-weight: 400;font-size: 14px;'>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">CPU-UsagePercent:${cpuUsage}%</span> <span style='font-size: 10px;background-color: ${colors[state]};' class="uk-label uk-label-success">${state}</span></li>`;
|
|
||||||
}
|
|
||||||
element.innerHTML = html;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function showThreadInfo(id) {
|
|
||||||
let stacks = threadMap[id];
|
|
||||||
let html = '';
|
|
||||||
for (let i = 0; i < stacks.length; i++) {
|
|
||||||
let stack = stacks[i];
|
|
||||||
let className = stack['className']
|
|
||||||
let methodName = stack['methodName']
|
|
||||||
let fileName = stack['fileName']
|
|
||||||
let lineNumber = stack['lineNumber']
|
|
||||||
html+=`<li style='color: #333;font-weight: 400;font-size: 14px;'>${className}.${methodName} <span style='font-size: 10px;background-color: darkslategray;text-transform: unset' class="uk-label uk-label-success">${fileName}:${lineNumber}</span></li>`;
|
|
||||||
|
|
||||||
}
|
|
||||||
let threadDetailDom = document.getElementById('thread-detail');
|
|
||||||
threadDetailDom.innerHTML = html;
|
|
||||||
UIkit.notification.closeAll();
|
|
||||||
UIkit.modal(document.getElementById("modal-thread")).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
refreshData();
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<!--endreplace-->
|
|
||||||
<body style="background-color: #f2f3f2" >
|
|
||||||
|
|
||||||
<nav class="uk-navbar-container" style="background-color: #404b67;height: 85px" uk-navbar>
|
|
||||||
<div class="uk-navbar-center">
|
|
||||||
<div class="uk-grid-small" uk-grid>
|
|
||||||
<div onclick="refreshData()" style="margin-top: 20px;font-size: 24px;color: white;cursor: pointer" class="uk-width-expand" >KoTime</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<ul class="uk-flex-center" uk-tab style="background-color: #404b67;margin-top: 0px;">
|
|
||||||
<li id="zl" class="uk-active"><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Summary</a></li>
|
|
||||||
<li id="jklb"><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Interfaces</a></li>
|
|
||||||
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Exceptions</a></li>
|
|
||||||
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Threads</a></li>
|
|
||||||
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Hot update</a></li>
|
|
||||||
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Configurations</a></li>
|
|
||||||
<li><a href="#" style="color: #edeef1;font-size: 14px;text-transform: capitalize">Contact me</a><span title="Latest release" style="position: absolute;top:-10px;left: 90%;border-radius: 5px;text-transform: unset" class="uk-label" id="version-notice" onclick="window.location.href='http://www.kotime.cn/docs/kaiyuan#/v220/introduce'"></span></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul class="uk-switcher uk-margin">
|
|
||||||
<li style="margin-left: 30%;margin-right: 30%;">
|
|
||||||
<ul class="uk-flex-left" uk-tab>
|
|
||||||
<li class="uk-active"><a href="#" style="text-transform: capitalize" >Number of Interface</a></li>
|
|
||||||
</ul>
|
|
||||||
<div style="margin-top: 20px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
|
||||||
<div>
|
|
||||||
<div id="systemTotalNum-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
|
||||||
className="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">All</span><br>
|
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="systemTotalNum">0</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div id="systemDelayNum-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
|
||||||
className="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">Delayed</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #cc0c0c;font-weight: bold" id="systemDelayNum">0</span></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div id="systemNormalNum-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
|
||||||
className="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">Normal</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #29da93;font-weight: bold" id="systemNormalNum">0</span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul style="margin-top: 10px;" class="uk-flex-left" uk-tab>
|
|
||||||
<li class="uk-active"><a href="#" style="text-transform: capitalize">Response Time</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="systemAvgRunTime-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
|
||||||
className="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">Avg(ms)</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="systemAvgRunTime">0</span></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div id="systemMaxRunTime-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
|
||||||
className="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">Max(ms)</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="systemMaxRunTime">0</span></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div id="systemMinRunTime-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px"
|
|
||||||
className="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">Min(ms)</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="systemMinRunTime">0</span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ul class="uk-flex-left" uk-tab>
|
|
||||||
<li class="uk-active"><a href="#" style="text-transform: capitalize">System Usage</a></li>
|
|
||||||
</ul>
|
|
||||||
<div style="margin-top: 20px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
|
||||||
<div>
|
|
||||||
<div id="cpuInfo-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 12px;color: #3b3f4f;justify-content: space-around;text-transform: unset" id="cpuLogicalAmount">CPU Usage:</span><span style="font-size: 15px;color: #020718;font-weight: bold" id="systemLoad" >0</span>
|
|
||||||
<hr style="margin-top: 7px">
|
|
||||||
<ul class="uk-list-bullet" style="text-align: left;margin-top: -13px">
|
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;text-transform: unset">User Usage:</span><span 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;text-transform: unset">System 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;text-transform: unset">IO Wait Rate:</span><span style="font-size: 12px;color: #020718;font-weight: bold" id="cpuWaitRate" >0</span></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div id="heapMemory-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 12px;color: #3b3f4f;justify-content: space-around;text-transform: unset">Heap Memory:</span><span style="font-size: 15px;color: #020718;font-weight: bold" id="heapUsedRate" >0</span>
|
|
||||||
<hr style="margin-top: 7px">
|
|
||||||
<ul class="uk-list-bullet" style="text-align: left;margin-top: -13px">
|
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;text-transform: unset">Init:</span><span style="font-size: 12px;color: #020718;font-weight: bold" id="heapInit" >0</span></li>
|
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;text-transform: unset">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;text-transform: unset">Used:</span><span style="font-size: 12px;color: #020718;font-weight: bold" id="heapUsed" >0</span></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div id="physicalMemory-div" style="border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 12px;color: #3b3f4f;justify-content: space-around;text-transform: unset">Physical Memory:</span><span style="font-size: 15px;color: #020718;font-weight: bold" id="physicalUsedRate" >0</span>
|
|
||||||
<hr style="margin-top: 7px">
|
|
||||||
<ul class="uk-list-bullet" style="text-align: left;margin-top: -13px">
|
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;text-transform: unset">All:</span><span style="font-size: 12px;color: #020718;font-weight: bold" id="physicalAmount" >0</span></li>
|
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;text-transform: unset">Used:</span><span style="font-size: 12px;color: #020718;font-weight: bold" id="physicalUsed" >0</span></li>
|
|
||||||
<li style="margin-top: -2px;"><span style="font-size: 8px;color: #3b3f4f;text-transform: unset">ThisUsed:</span><span style="font-size: 12px;color: #020718;font-weight: bold" id="thisUsed" >0</span></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-alert-success" uk-alert>
|
|
||||||
<a class="uk-alert-close" uk-close></a>
|
|
||||||
<p id="apiTip">Please call apis before visiting this page!</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li style="margin-left: 20%;margin-right: 20%;">
|
|
||||||
<div style="left: 35%;width: 350px;" class="uk-search uk-search-default">
|
|
||||||
<span uk-search-icon></span>
|
|
||||||
<input list="condidates" id="searchText" style="border-top: none;border-right: none;border-left: none;border-bottom: 1px solid lightgreen;color:#213121" class="uk-search-input" type="search" placeholder="search method name or class name..." oninput="searchTip(event);" onkeydown="searchApis(event);">
|
|
||||||
<datalist id="condidates" onkeydown="searchApis(event);">
|
|
||||||
</datalist>
|
|
||||||
</div>
|
|
||||||
<ul id="apiList" style="background-color: rgba(245,242,242,0.96);padding: 10px;overflow-y: auto;max-height: 70%" class="uk-list uk-list-divider">
|
|
||||||
<li>method 1 1 <span class="uk-label uk-label-success">0</span></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li style="margin-left: 20%;margin-right: 20%;">
|
|
||||||
<ul id="exceptionList" style="background-color: rgba(245,242,242,0.96);padding: 10px;overflow-y: auto;max-height: 73%" class="uk-list uk-list-divider">
|
|
||||||
<li>exception 1 1 <span class="uk-label uk-label-danger">closed</span></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li style="margin-left: 30%;margin-right: 30%;">
|
|
||||||
<ul class="uk-flex-left" uk-tab>
|
|
||||||
<li class="uk-active"><a href="#" style="text-transform: capitalize">Number of thread</a></li>
|
|
||||||
</ul>
|
|
||||||
<div style="margin-top: 20px;" class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid>
|
|
||||||
<div>
|
|
||||||
<div onclick="loadThreadsInfo('')" id="threadNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">ALL</span><br>
|
|
||||||
<span style="font-size: 30px;color: #020718;font-weight: bold" id="threadNum" >0</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div onclick="loadThreadsInfo('RUNNABLE')" id="runnableNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">RUNNABLE</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #29da93;font-weight: bold" id="runnableNum">0</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div onclick="loadThreadsInfo('BLOCKED')" id="blockedNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">BLOCKED</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #cc0c0c;font-weight: bold" id="blockedNum">0</span></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div onclick="loadThreadsInfo('WAITING')" id="waitingNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">WAITING</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #ad7070;font-weight: bold" id="waitingNum">0</span></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div onclick="loadThreadsInfo('TIMED_WAITING')" id="timedWaitingNum-div" style="cursor:pointer;border-radius: 10px;background-color: #fefffe;padding: 20px" class="uk-card uk-card-default uk-card-body uk-label-success">
|
|
||||||
<span style="font-size: 10px;color: #3b3f4f">TIMED_WAITING</span>
|
|
||||||
<br>
|
|
||||||
<span style="font-size: 30px;color: #ad7070;font-weight: bold" id="timedWaitingNum">0</span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ul class="uk-flex-left" uk-tab>
|
|
||||||
<li class="uk-active"><a href="#" style="text-transform: capitalize">Threads</a></li>
|
|
||||||
</ul>
|
|
||||||
<ul id="threadList" style="background-color: rgba(245,242,242,0.96);padding: 10px;overflow-y: auto;max-height: 65%" class="uk-list uk-list-divider">
|
|
||||||
<li>thread 1 1 <span class="uk-label uk-label-success">0</span></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li style="margin-left: 35%;margin-right: 35%;">
|
|
||||||
<div class="uk-card uk-card-default uk-card-body">
|
|
||||||
<div id="classForm" >
|
|
||||||
<div uk-form-custom="target: true" class="uk-form-controls">
|
|
||||||
<input id="classFile" name="classFile" type="file" >
|
|
||||||
<input id="form-file" style="width: 500px;border-radius: 5px" class="uk-input" type="text" placeholder="class file needed to update:compiled class file" >
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<input id="className" name="className" style="width: 500px;border-radius: 5px" class="uk-input" id="" type="text" placeholder="class name needed to update :com.xx.xx.TestService" >
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<button type="button" onclick="updateClass();" style="width: 500px;background-color: #19985d;border-radius: 5px" class="uk-button uk-button-primary uk-width-1-1 uk-margin-small-bottom">OK</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li style="margin-left: 30%;margin-right: 30%;">
|
|
||||||
<ul class="uk-flex-left" uk-tab>
|
|
||||||
<li class="uk-active"><a href="#" style="text-transform: unset">KoTime Configuration</a></li>
|
|
||||||
<li class=""><a href="#" style="text-transform: unset">dynamic.properties Configuration</a></li>
|
|
||||||
</ul>
|
|
||||||
<ul class="uk-switcher uk-margin">
|
|
||||||
<li>
|
|
||||||
<div style="margin-top: 20px;" class="uk-grid-small uk-child-width-expand@s uk-text-left uk-card uk-card-default uk-card-body" style="border-radius: 5px" uk-grid>
|
|
||||||
<div class="layui-tab-item">
|
|
||||||
<label >KoTime switch:</label> <input id='kotimeEnable' type="checkbox" checked>
|
|
||||||
<br>
|
|
||||||
<label >exception switch:</label> <input id='exceptionEnable' type="checkbox">
|
|
||||||
<br>
|
|
||||||
<label >console log switch:</label> <input id='logEnable' type="checkbox">
|
|
||||||
<br>
|
|
||||||
<label >email switch:</label> <input id='mailEnable' type="checkbox">
|
|
||||||
<br>
|
|
||||||
<label>language switch:</label>
|
|
||||||
<select id="languageSwitch" >
|
|
||||||
<option value="chinese">Chinese</option>
|
|
||||||
<option value="english">English</option>
|
|
||||||
</select>
|
|
||||||
<br>
|
|
||||||
<label >time threshold:</label> <input id='timeThreshold' type="input"><button style="background-color: #177ce1;border: 1px solid #177ce1;cursor: pointer;color: white" id="timeThresholdYes">OK</button>
|
|
||||||
<br>
|
|
||||||
<label >clear data:</label><button style="background-color: #177ce1;border: 1px solid #177ce1;cursor: pointer;color: white" id="clearDataYes">OK</button>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<div class="uk-alert-success" uk-alert>
|
|
||||||
<a class="uk-alert-close" uk-close></a>
|
|
||||||
<p>Please refresh this page after updating configurations</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="uk-card uk-card-default uk-card-body" style="border-radius: 5px">
|
|
||||||
<textarea id="dynamicText" class="uk-textarea" placeholder="" wrap="off" style="overflow-y: auto;height: 65%;resize: none;overflow-x: auto;"></textarea>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<button type="button" onclick="updateDynamicProperties();" style="width: 100%;background-color: #19985d;border-radius: 5px" class="uk-button uk-button-primary uk-width-1-1 uk-margin-small-bottom">OK</button>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li style="margin-left: 30%;margin-right: 30%;">
|
|
||||||
<script src='https://gitee.com/huoyo/ko-time/widget_preview' async defer></script>
|
|
||||||
<div id="osc-gitee-widget-tag"></div>
|
|
||||||
<style>
|
|
||||||
.osc_pro_color {color: #ffffff !important;}
|
|
||||||
.osc_panel_color {background-color: #1e252b !important;}
|
|
||||||
.osc_background_color {background-color: #323d47 !important;}
|
|
||||||
.osc_border_color {border-color: #455059 !important;}
|
|
||||||
.osc_desc_color {color: #d7deea !important;}
|
|
||||||
.osc_link_color * {color: #99a0ae !important;}
|
|
||||||
</style>
|
|
||||||
<br>
|
|
||||||
<div class="uk-alert-success" uk-alert>
|
|
||||||
<a class="uk-alert-close" uk-close></a>
|
|
||||||
<a href="http://www.kotime.cn/#doc?version=v2.3.7">Technical support</a><br>
|
|
||||||
<a href="http://www.kotime.cn/#products?version=v2.3.7">KoTime Pro</a><br>
|
|
||||||
<a href="http://www.kotime.cn/person?version=v2.3.7">Local plugin</a></div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div id="modal-thread" uk-modal>
|
|
||||||
<div class="uk-modal-dialog" style="width: 75%">
|
|
||||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
|
||||||
<div class="uk-modal-body uk-margin-auto-vertical" uk-overflow-auto>
|
|
||||||
<ul id="thread-detail" style="background-color: rgba(245,242,242,0.96);padding: 10px;overflow-y: auto;max-height: 70%" class="uk-list uk-list-divider">
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="uk-modal-footer uk-text-right">
|
|
||||||
<button class="uk-button uk-button-primary uk-modal-close" type="button">OK</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="modal-exception" uk-modal>
|
|
||||||
<div class="uk-modal-dialog">
|
|
||||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
|
||||||
<div id="exception-detail" class="uk-modal-body uk-margin-auto-vertical" uk-overflow-auto>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="uk-modal-footer uk-text-right">
|
|
||||||
<button class="uk-button uk-button-primary uk-modal-close" type="button">OK</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="modal-method" class="uk-modal-full" uk-modal>
|
|
||||||
<div class="uk-modal-dialog">
|
|
||||||
<button class="uk-modal-close-full uk-close-large" type="button" uk-close></button>
|
|
||||||
<div class="uk-grid-collapse uk-child-width-1-1@s uk-flex-middle" uk-grid>
|
|
||||||
<div uk-height-viewport>
|
|
||||||
<div id="layerDemo" width="1200px" height="900px">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="modal-login" class="uk-modal-full" uk-modal>
|
|
||||||
|
|
||||||
<div class="uk-modal-dialog" style="background-color: rgb(242, 243, 242)">
|
|
||||||
<div class="uk-grid-collapse uk-child-width-1-1@s uk-flex-middle" uk-grid>
|
|
||||||
<div uk-height-viewport>
|
|
||||||
|
|
||||||
<div class="uk-text-center" uk-grid>
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-3@m" style="margin-top: 100px;">
|
|
||||||
<form class="uk-card uk-card-default uk-card-body" style="border-radius: 5px">
|
|
||||||
<div class="uk-margin">
|
|
||||||
<div class="uk-inline">
|
|
||||||
<div style="font-size: 35px;" class="uk-width-expand" >KoTime</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div class="uk-margin">
|
|
||||||
<div class="uk-inline">
|
|
||||||
<span class="uk-form-icon" uk-icon="icon: user"></span>
|
|
||||||
<input id="userName" class="uk-input" type="text">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-margin">
|
|
||||||
<div class="uk-inline">
|
|
||||||
<span class="uk-form-icon uk-form-icon-flip" uk-icon="icon: lock"></span>
|
|
||||||
<input id="userPassword" type="password" class="uk-input" >
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-margin">
|
|
||||||
<div class="uk-inline">
|
|
||||||
<a class="uk-button uk-button-default uk-label-success" style="border-radius: 5px" onclick="login();" >OK</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--<div class="uk-margin-medium-bottom" style="position:absolute;top:95%;left:45%;text-align:center;">-->
|
|
||||||
<!-- <ul class="uk-flex-center" uk-tab>-->
|
|
||||||
<!-- <li class=""><a style="font-size: 7px;text-transform:capitalize" href="#">@2021 Huoyo</a></li>-->
|
|
||||||
<!-- </ul>-->
|
|
||||||
<!--</div>-->
|
|
||||||
|
|
||||||
</body>
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user