diff --git a/.gitignore b/.gitignore index db66bd2..aeca68d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ target/ .txlcn *.log /.idea/ +/.idea/ diff --git a/pom.xml b/pom.xml index 9056994..2c8b1bd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.langpy ko-time - 2.4.4 + 2.4.5 KoTime A springboot tool for tracking the paths of the methods,which can help you find method's performances easily. diff --git a/src/main/java/cn/langpy/kotime/constant/KoConstant.java b/src/main/java/cn/langpy/kotime/constant/KoConstant.java index 1076de9..eb1bad4 100644 --- a/src/main/java/cn/langpy/kotime/constant/KoConstant.java +++ b/src/main/java/cn/langpy/kotime/constant/KoConstant.java @@ -9,12 +9,11 @@ public class KoConstant { public final static String exceptionTitleStyle = "exceptionTitleStyle"; public final static String globalThreshold = "globalThresholdValue"; public final static String globalNeedLogin = "globalNeedLoginValue"; - public final static String globalIsLogin = "globalIsLoginValue"; public final static String contextPath = "contextPath"; public final static String kotimeViewer = "kotime.html"; public final static String kotimeViewerEn = "kotime-en.html"; - public final static String loginName = "kotimeUserName"; + @Deprecated public static String getViewName(String language) { if (!StringUtils.hasText(language)) { language = Context.getConfig().getLanguage(); diff --git a/src/main/java/cn/langpy/kotime/controller/KoInitController.java b/src/main/java/cn/langpy/kotime/controller/KoInitController.java new file mode 100644 index 0000000..224b513 --- /dev/null +++ b/src/main/java/cn/langpy/kotime/controller/KoInitController.java @@ -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 ""; + } + + +} diff --git a/src/main/java/cn/langpy/kotime/controller/KoTimeController.java b/src/main/java/cn/langpy/kotime/controller/KoTimeController.java index 42daedb..66772d7 100644 --- a/src/main/java/cn/langpy/kotime/controller/KoTimeController.java +++ b/src/main/java/cn/langpy/kotime/controller/KoTimeController.java @@ -2,24 +2,17 @@ package cn.langpy.kotime.controller; import cn.langpy.kotime.annotation.Auth; import cn.langpy.kotime.config.DefaultConfig; -import cn.langpy.kotime.constant.KoConstant; import cn.langpy.kotime.model.*; import cn.langpy.kotime.service.ClassService; import cn.langpy.kotime.service.GraphService; import cn.langpy.kotime.service.SysUsageService; import cn.langpy.kotime.service.ThreadUsageService; 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.util.StringUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.*; import java.util.logging.Logger; @@ -33,132 +26,7 @@ import static cn.langpy.kotime.model.ThreadInfo.COMPARATOR; @Controller @RequestMapping("/koTime") 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 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") diff --git a/src/main/java/cn/langpy/kotime/util/KoUtil.java b/src/main/java/cn/langpy/kotime/util/KoUtil.java index 21eb9bb..f54198d 100644 --- a/src/main/java/cn/langpy/kotime/util/KoUtil.java +++ b/src/main/java/cn/langpy/kotime/util/KoUtil.java @@ -5,14 +5,21 @@ import cn.langpy.kotime.model.InvokedInfo; import cn.langpy.kotime.model.MethodNode; import cn.langpy.kotime.service.InvokedQueue; 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.StringRedisTemplate; +import org.springframework.util.StringUtils; import javax.sql.DataSource; +import java.io.*; +import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.logging.Logger; import java.util.stream.Collectors; public class KoUtil { + private static Logger log = Logger.getLogger(KoUtil.class.toString()); + private final static String koTimeSecret = UUID.randomUUID().toString().replace("-", ""); private final static List choices = randomSecretIndexs(); @@ -215,5 +222,47 @@ public class KoUtil { 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"); + } + + } diff --git a/src/main/resources/koapp.properties b/src/main/resources/koapp.properties new file mode 100644 index 0000000..a8e0da4 --- /dev/null +++ b/src/main/resources/koapp.properties @@ -0,0 +1 @@ +ko-time.version=2.4.5 \ No newline at end of file diff --git a/src/main/resources/kostatic/dict/chinese.properties b/src/main/resources/kostatic/dict/chinese.properties new file mode 100644 index 0000000..13d129b --- /dev/null +++ b/src/main/resources/kostatic/dict/chinese.properties @@ -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=本地化插件 \ No newline at end of file diff --git a/src/main/resources/kostatic/dict/english.properties b/src/main/resources/kostatic/dict/english.properties new file mode 100644 index 0000000..b25b1c3 --- /dev/null +++ b/src/main/resources/kostatic/dict/english.properties @@ -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 \ No newline at end of file diff --git a/src/main/resources/kostatic/util.js b/src/main/resources/kostatic/util.js new file mode 100644 index 0000000..11e0b03 --- /dev/null +++ b/src/main/resources/kostatic/util.js @@ -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(""+message+"", {}); +} + +function noticeError(message){ + UIkit.notification.closeAll(); + UIkit.notification(""+message+"", {}); +} \ No newline at end of file diff --git a/src/main/resources/kotime-en.html b/src/main/resources/kotime-en.html deleted file mode 100644 index 38cfbe9..0000000 --- a/src/main/resources/kotime-en.html +++ /dev/null @@ -1,992 +0,0 @@ - - - - KoTime - - - - - - - - - - - - - - KoTime - - - - - - Summary - Interfaces - Exceptions - Threads - Hot update - Configurations - Contact me - - - - - - Number of Interface - - - - - All - 0 - - - - - Delayed - - 0 - - - - Normal - - 0 - - - - - Response Time - - - - - Avg(ms) - - 0 - - - - Max(ms) - - 0 - - - - Min(ms) - - 0 - - - - System Usage - - - - - CPU Usage:0 - - - User Usage:0 - System Usage:0 - IO Wait Rate:0 - - - - - - Heap Memory:0 - - - Init:0 - Max:0 - Used:0 - - - - - - Physical Memory:0 - - - All:0 - Used:0 - ThisUsed:0 - - - - - - - Please call apis before visiting this page! - - - - - - - - - - - method 1 1 0 - - - - - exception 1 1 closed - - - - - Number of thread - - - - - ALL - 0 - - - - - RUNNABLE - - 0 - - - - - BLOCKED - - 0 - - - - WAITING - - 0 - - - - TIMED_WAITING - - 0 - - - - Threads - - - thread 1 1 0 - - - - - - - - - - - - - - - OK - - - - - - KoTime Configuration - dynamic.properties Configuration - - - - - - KoTime switch: - - exception switch: - - console log switch: - - email switch: - - language switch: - - Chinese - English - - - time threshold: OK - - clear data:OK - - - - - - Please refresh this page after updating configurations - - - - - - - - - - OK - - - - - - - - - - - - - Technical support - KoTime Pro - Local plugin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KoTime - - - - - - - - - - - - - - - - - - OK - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/kotime.html b/src/main/resources/kotime.html index 48892c4..5f91969 100644 --- a/src/main/resources/kotime.html +++ b/src/main/resources/kotime.html @@ -1,46 +1,43 @@ - KoTime - - - - @@ -636,105 +641,138 @@ - KoTime调用链路追踪 + {{kotime-title}} + - 总览 - 接口列表 - 异常列表 - 线程列表 - 热更新 - 配置 - 技术支持 + {{tab.summary}} + {{tab.interface}} + {{tab.exception}} + {{tab.thread}} + {{tab.hotupdate}} + {{tab.configuration}} + {{tab.support}} + + - 接口统计 + {{tab.summary.interface-metric}} - - 接口数 - 0 + + {{tab.summary.interface-metric.total-num}} + 0 - - 延迟响应数 + + {{tab.summary.interface-metric.delay-num}} 0 - - 正常响应数 + + {{tab.summary.interface-metric.normal-num}} 0 - 响应统计 + {{tab.summary.response-metric}} - - 平均响应(ms) + + {{tab.summary.response-metric.avg-num}} 0 - - 最大响应(ms) + + {{tab.summary.response-metric.max-num}} 0 - - 最小响应(ms) + + {{tab.summary.response-metric.min-num}} 0 - 系统使用情况 + {{tab.summary.sysusage-metric}} - - CPU使用率:0 + + {{tab.summary.sysusage-metric.cpu-usage}}:0 - - 用户使用率:0 - 系统使用率:0 - IO 等待率:0 + + {{tab.summary.sysusage-metric.cpu-usage.user-usage}}:0 + {{tab.summary.sysusage-metric.cpu-usage.sys-usage}}:0 + {{tab.summary.sysusage-metric.cpu-usage.io-waiting}}:0 - - 堆内存:0 + + {{tab.summary.sysusage-metric.heap-memory}}:0 - - 初始值:0 - 最大值:0 - 已使用:0 + + {{tab.summary.sysusage-metric.heap-memory.init}}:0 + {{tab.summary.sysusage-metric.heap-memory.max}}:0 + {{tab.summary.sysusage-metric.heap-memory.used}}:0 - - 物理内存:0 + + {{tab.summary.sysusage-metric.physical-memory}}:0 - - 总物理内存:0 - 已使用内存:0 - 此程序占用:0 + + {{tab.summary.sysusage-metric.physical-memory.total}}:0 + + {{tab.summary.sysusage-metric.physical-memory.used}}:0 + {{tab.summary.sysusage-metric.physical-memory.current-used}}:0 @@ -742,126 +780,161 @@ - 接口根据调用情况统计,未调用的接口无法被统计到,请先调用接口 + {{tab.summary.bottom-normal-tip}} - + - + method 1 1 0 - + exception 1 1 未开启 - 线程统计 + {{tab.thread.thread-metric}} - + ALL - 0 + 0 - + RUNNABLE 0 - + BLOCKED 0 - + WAITING 0 - + TIMED_WAITING 0 - 线程列表 + {{tab.thread.thread-list}} - + thread 1 1 0 - - - - + + + + - + - 确定 + {{kotime-confirm}} + - KoTime配置 - dynamic.properties配置 + {{tab.configuration.kotime-config}} + {{tab.configuration.dynamic-config}} - - - 开启koTime: + + + {{tab.configuration.kotime-config.enable-kotime-tip}}: - 开启异常监测: + {{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.bottom-tip}} - + - 更新 + {{tab.configuration.dynamic-config.confirm-name}} + @@ -871,19 +944,36 @@ - 技术支持 - 升级专业版 - 本地化插件 + {{tab.support.support-tip}} + {{tab.support.pro-tip}} + {{tab.support.plugin-tip}} @@ -891,12 +981,14 @@ - - + + @@ -909,7 +1001,7 @@ @@ -931,16 +1023,16 @@ - + - + - KoTime调用链路追踪 + {{kotime-title}} @@ -953,12 +1045,13 @@ - + - 确定 + {{kotime-confirm}} @@ -974,8 +1067,6 @@ - -
Please call apis before visiting this page!
Please refresh this page after updating configurations
接口根据调用情况统计,未调用的接口无法被统计到,请先调用接口
{{tab.summary.bottom-normal-tip}}
变更配置以后请重新刷新页面
{{tab.configuration.bottom-tip}}