diff --git a/kernel-o-monitor/monitor-api/src/main/java/cn/stylefeng/roses/kernel/monitor/api/constants/MonitorConstants.java b/kernel-o-monitor/monitor-api/src/main/java/cn/stylefeng/roses/kernel/monitor/api/constants/MonitorConstants.java
index c3ed1a490..cfcb28d9f 100644
--- a/kernel-o-monitor/monitor-api/src/main/java/cn/stylefeng/roses/kernel/monitor/api/constants/MonitorConstants.java
+++ b/kernel-o-monitor/monitor-api/src/main/java/cn/stylefeng/roses/kernel/monitor/api/constants/MonitorConstants.java
@@ -23,11 +23,6 @@ public interface MonitorConstants {
*/
String MONITOR_PROMETHEUS_QUERY = "query";
- /**
- * prometheus查询区间向量命令
- */
- String MONITOR_PROMETHEUS_QUERY_RANGE = "query_range";
-
/**
* prometheus查询开始时间
*/
@@ -42,4 +37,10 @@ public interface MonitorConstants {
* prometheus查询步长
*/
String MONITOR_PROMETHEUS_STEP = "step";
+
+ /**
+ * prometheus查询区间向量命令
+ */
+ String PROMETHEUS_QUERY_RANGE = "query_range";
+
}
diff --git a/kernel-o-monitor/monitor-integration-beetl/README.md b/kernel-o-monitor/monitor-integration-beetl/README.md
new file mode 100644
index 000000000..a48bf3446
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/README.md
@@ -0,0 +1 @@
+监控模块的集成,针对于beetl模板引擎单体不分离项目
diff --git a/kernel-o-monitor/monitor-integration-beetl/pom.xml b/kernel-o-monitor/monitor-integration-beetl/pom.xml
new file mode 100644
index 000000000..9674b9a86
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+
+ cn.stylefeng.roses
+ kernel-o-monitor
+ 7.0.1
+ ../pom.xml
+
+
+ monitor-integration-beetl
+
+ jar
+
+
+
+
+
+ cn.stylefeng.roses
+ monitor-spring-boot-starter
+ 7.0.1
+
+
+
+
+
+ cn.stylefeng.roses
+ scanner-api
+ 7.0.1
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
diff --git a/kernel-o-monitor/monitor-integration-beetl/src/main/java/cn/stylefeng/roses/kernel/monitor/integration/config/PrometheusConfiguration.java b/kernel-o-monitor/monitor-integration-beetl/src/main/java/cn/stylefeng/roses/kernel/monitor/integration/config/PrometheusConfiguration.java
new file mode 100644
index 000000000..dab964bfb
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/src/main/java/cn/stylefeng/roses/kernel/monitor/integration/config/PrometheusConfiguration.java
@@ -0,0 +1,42 @@
+package cn.stylefeng.roses.kernel.monitor.integration.config;
+
+import cn.stylefeng.roses.kernel.monitor.api.PrometheusApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.Resource;
+
+/**
+ * 是否显示prometheus菜单
+ *
+ * @author chenli
+ * @date 2021/3/3 17:14
+ */
+@Configuration
+@Slf4j
+public class PrometheusConfiguration {
+
+ @Value("${prometheus.enabled}")
+ private boolean prometheusEnabled;
+
+ @Resource
+ private PrometheusApi prometheusApi;
+
+ /***
+ * 配置是否开启prometheus相关菜单
+ *
+ * @author chenli
+ * @date 2021/3/3 17:14
+ */
+ @Bean
+ public void configPrometheusMenu() {
+ if (prometheusEnabled) {
+ prometheusApi.displayPrometheusMenu();
+ } else {
+ prometheusApi.closePrometheusMenu();
+ }
+ }
+
+}
diff --git a/kernel-o-monitor/monitor-integration-beetl/src/main/java/cn/stylefeng/roses/kernel/monitor/integration/controller/MonitorController.java b/kernel-o-monitor/monitor-integration-beetl/src/main/java/cn/stylefeng/roses/kernel/monitor/integration/controller/MonitorController.java
new file mode 100644
index 000000000..87784bab7
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/src/main/java/cn/stylefeng/roses/kernel/monitor/integration/controller/MonitorController.java
@@ -0,0 +1,297 @@
+package cn.stylefeng.roses.kernel.monitor.integration.controller;
+
+import cn.hutool.core.util.StrUtil;
+import cn.stylefeng.roses.kernel.monitor.api.PrometheusApi;
+import cn.stylefeng.roses.kernel.monitor.api.constants.MonitorConstants;
+import cn.stylefeng.roses.kernel.monitor.api.pojo.prometheus.PromResultInfo;
+import cn.stylefeng.roses.kernel.monitor.system.holder.SystemHardwareInfoHolder;
+import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource;
+import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 项目监控
+ *
+ * @author chenli
+ * @date 2020/12/30 16:40
+ */
+@Controller
+@ApiResource(name = "项目监控")
+public class MonitorController {
+
+ @Resource
+ private SystemHardwareInfoHolder systemHardwareInfoHolder;
+
+ @Value("${spring.application.name}")
+ private String name;
+
+ @Value("${prometheus.url}")
+ private String prometheusUrl;
+
+ @Value("${prometheus.instance}")
+ private String prometheusInstance;
+
+ @Resource
+ private PrometheusApi service;
+
+ /**
+ * 系统硬件信息页面
+ *
+ * @author fengshuonan
+ * @date 2018/12/24 22:43
+ */
+ @GetResource(name = "服务器监控", path = "/view/monitor/systemInfo")
+ public String systemInfo(Model model) {
+ model.addAttribute("server", systemHardwareInfoHolder.getSystemHardwareInfo());
+ return "/modular/system/monitor/systemInfo.html";
+ }
+
+ /**
+ * druid sql监控页面
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "SQL监控", path = "/view/monitor/druid")
+ public String druidInfo() {
+ return "/modular/system/monitor/druid.html";
+ }
+
+ /**
+ * tomcat监控页面
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "tomcat监控首页", path = "/view/monitor/tomcatInfo")
+ public String tomcatIndex() {
+ return "/modular/system/monitor/tomcatInfo.html";
+ }
+
+ /**
+ * tomcat监控数据
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "tomcat监控数据", path = "/view/monitor/getTomcatInfo")
+ @ResponseBody
+ public String tomcatInfo() {
+ Map metricMap = getMetricInfos(getPromQl(), "tomcat_", "", "");
+ return JSON.toJSONString(metricMap);
+ }
+
+ /**
+ * jvm监控页面
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "jvm监控页面", path = "/view/monitor/jvmInfo")
+ public String jvmIndex() {
+ return "/modular/system/monitor/jvmInfo.html";
+ }
+
+ /**
+ * jvm监控数据
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "jvm监控数据", path = "/view/monitor/getJvmInfo")
+ @ResponseBody
+ public String jvmInfo(@RequestParam("id") String id, @RequestParam("area") String area) {
+ Map metricMap = getMetricInfos(getPromQl(id, area), "jvm_", "", "");
+ return JSON.toJSONString(metricMap);
+ }
+
+ /**
+ * 性能监控页面
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "性能监控页面", path = "/view/monitor/performanceInfo")
+ public String performanceIndex() {
+ return "/modular/system/monitor/performanceInfo.html";
+ }
+
+ /**
+ * 性能监控数据
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "CPU监控数据", path = "/view/monitor/getCpuInfo")
+ @ResponseBody
+ public String cpuInfo() {
+ Map metricMap = getMetricInfos(getPromQl(), "cpu_", "", "");
+ return JSON.toJSONString(metricMap);
+ }
+
+ /**
+ * 服务器负载监控数据
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "服务器负载监控数据", path = "/view/monitor/getLoadInfo")
+ @ResponseBody
+ public String loadInfo() {
+ Map metricMap = getMetricInfos(getPromQl(), "system_", "", "");
+ return JSON.toJSONString(metricMap);
+ }
+
+ /**
+ * 进程监控数据
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "进程监控数据", path = "/view/monitor/getProcessInfo")
+ @ResponseBody
+ public String processInfo() {
+ Map metricMap = getMetricInfos(getPromQl(), "process_", "", "");
+ return JSON.toJSONString(metricMap);
+ }
+
+ /**
+ * 日志监控页面
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "日志监控页面", path = "/view/monitor/logbackInfo")
+ public String logbackIndex() {
+ return "/modular/system/monitor/logbackInfo.html";
+ }
+
+ /**
+ * 日志监控数据
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ @GetResource(name = "日志监控数据", path = "/view/monitor/getLogbackInfo")
+ @ResponseBody
+ public String logbackInfo(@RequestParam("level") String level, @RequestParam("timeInterval") String timeInterval, @RequestParam("isRate") String isRate, @RequestParam("rateMetric") String rateMetric) {
+ if (StrUtil.isEmpty(timeInterval)) {
+ timeInterval = "[5m]";
+ }
+ Map metricMap = getMetricInfos(getIratePromQl(level, timeInterval), "logback_", isRate, rateMetric);
+ return JSON.toJSONString(metricMap);
+ }
+
+ /**
+ * 组装prometheus查询sql
+ *
+ * @param id 同一指标不同分类的id号
+ * @param area 查询区域jvm常用
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ private String getPromQl(String id, String area) {
+ StringBuilder promql = new StringBuilder("{application=\"");
+ promql.append(name);
+ if (!StrUtil.isEmpty(id)) {
+ promql.append("\",id=\"");
+ promql.append(id);
+ }
+ if (!StrUtil.isEmpty(area)) {
+ promql.append("\",area=\"");
+ promql.append(area);
+ }
+ if (!StrUtil.isEmpty(prometheusInstance)) {
+ promql.append("\",instance=\"");
+ promql.append(prometheusInstance);
+ }
+ promql.append("\"}");
+ return promql.toString();
+ }
+
+ /**
+ * 组装prometheus查询sql方法重写不带参数
+ *
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ private String getPromQl() {
+ StringBuilder promql = new StringBuilder("{application=\"");
+ promql.append(name);
+ if (!StrUtil.isEmpty(prometheusInstance)) {
+ promql.append("\",instance=\"");
+ promql.append(prometheusInstance);
+ }
+ promql.append("\"}");
+ return promql.toString();
+ }
+
+ /**
+ * 组装prometheus平均值查询sql方法重写不带参数
+ *
+ * @param level 日志统计查询参数,info、warn、error、trace、debug
+ * @param timeInterval 统计时间区间单位通常为分钟(m)
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ private String getIratePromQl(String level, String timeInterval) {
+ StringBuilder promql = new StringBuilder("{application=\"");
+ promql.append(name);
+ if (!StrUtil.isEmpty(prometheusInstance)) {
+ promql.append("\",instance=\"");
+ promql.append(prometheusInstance);
+ }
+ if (!StrUtil.isEmpty(level)) {
+ promql.append("\",level=\"");
+ promql.append(level);
+ }
+ promql.append("\"}");
+ promql.append(timeInterval);
+ return promql.toString();
+ }
+
+ /**
+ * 分别输出监控名称以及对应的值
+ *
+ * @param promQL prometheus查询sql
+ * @param metric prometheus指标前缀,比如:"jvm_"
+ * @param isRate prometheus计算函数,不需要计算周期内值就直接为"",需要计算则写计算函数以及对应的指标
+ * @author chenli
+ * @date 2021/1/4 16:32
+ */
+ private Map getMetricInfos(String promQL, String metric, String isRate, String rateMetric) {
+ Map metricMap = new HashMap<>();
+ if (!StrUtil.isEmpty(prometheusUrl)) {
+ List promResultInfos = service.getMetricInfo(prometheusUrl.concat(MonitorConstants.PROMETHEUS_QUERY_RANGE), promQL, isRate, rateMetric);
+ if (Objects.isNull(promResultInfos)) {
+ return metricMap;
+ }
+ for (PromResultInfo promResultInfo : promResultInfos) {
+ String metricName = promResultInfo.getMetric().get__name__();
+ JSONArray valueArray = JSONArray.parseArray(JSON.toJSONString(promResultInfo.getValues()).replaceAll("\\\\", "").replace("\"", ""));
+ if (!StrUtil.isEmpty(metricName)) {
+ if (metricName.contains(metric)) {
+ // 得到的数据为数组,需要转为json字符串去除双引号再转化为JSONArray,JSONArray是echarts时间序列图需要的数据格式
+ metricMap.put(metricName, valueArray);
+ }
+ } else {
+ // 查询指定的指标
+ metricMap.put(rateMetric, valueArray);
+ }
+ }
+ }
+ return metricMap;
+ }
+}
diff --git a/kernel-o-monitor/monitor-integration-beetl/src/main/resources/META-INF/spring.factories b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/META-INF/spring.factories
new file mode 100644
index 000000000..3a9994383
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ cn.stylefeng.roses.kernel.monitor.integration.config.PrometheusConfiguration
diff --git a/kernel-o-monitor/monitor-integration-beetl/src/main/resources/assets/common/js/echartInit.js b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/assets/common/js/echartInit.js
new file mode 100644
index 000000000..6eb5e7e3b
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/assets/common/js/echartInit.js
@@ -0,0 +1,171 @@
+function initGraph(params){
+ const paramsId = echarts.init(document.getElementById(params.id), myEchartsTheme);
+ let metricData = params.metric;
+ const option = {
+ title: {
+ text: params.id,
+ x: 'center'
+ },
+ tooltip: {
+ trigger: 'axis',
+ formatter: function (datas){
+ let res;
+ datas.map(function (e,i) {
+ if (res == undefined){
+ let datetime = new Date(e.value[0]*1000);
+ res = datetime.getUTCFullYear().toString()+'-'+datetime.getUTCMonth().toString()+'-'+datetime.getUTCDate().toString()+' '+datetime.getHours().toString()+':'+ datetime.getMinutes().toString() + ':' + datetime.getSeconds().toString() + '
'
+ }
+ if (params.unit === 'MB' && e.value[1]>0){
+ res += e.marker +" " + e.seriesName + ' : ' + (e.value[1]/1000/1000).toFixed(2) + params.unit + '
'
+ } else {
+ res += e.marker +" " + e.seriesName + ' : ' + e.value[1] + '
'
+ }
+ })
+ return res;
+ }
+ },
+ xAxis: {
+ type: 'time',
+ axisLabel: {
+ formatter: function(value,index){
+ let datetime = new Date(value*1000)
+ return datetime.getHours().toString()+':'+ datetime.getMinutes().toString()
+ }
+ }
+ },
+ yAxis: {
+ name: params.unit,
+ type: 'value',
+ scale: true,
+ axisLabel: {
+ formatter: function(value,index){
+ if (params.unit == 'MB' && value>0){
+ return value/1000/1000
+ } else {
+ return value
+ }
+ }
+ }
+ },
+ series: [{type : 'line',
+ smooth: true,
+ animationDuration: 2000,
+ animationEasing: 'quadraticOut',
+ name : params.id,
+ data: metricData,
+ areaStyle: { // 折现下是否填充
+ color: this.color,
+ opacity: 0.6
+ },
+ showSymbol: false}],
+ };
+ paramsId.setOption(option);
+}
+
+// 初始化三个数据指标
+function initMultiGraph(multiParams){
+ const multiParamsId = echarts.init(document.getElementById(multiParams.id), myEchartsTheme);
+ let metricData = multiParams.metric;
+ const option = {
+ title: { text: multiParams.title, x: 'center' },
+ tooltip: {
+ trigger: 'axis',
+ formatter: function (datas){
+ let res;
+ datas.map(function (e,i) {
+ if (res == undefined){
+ let datetime = new Date(e.value[0]*1000);
+ res = datetime.getUTCFullYear().toString()+'-'+datetime.getUTCMonth().toString()+'-'+datetime.getUTCDate().toString()+' '+datetime.getHours().toString()+':'+ datetime.getMinutes().toString() + ':' + datetime.getSeconds().toString() + '
'
+ }
+ if (multiParams.unit === 'MB' && e.value[1]>0){
+ res += e.marker +" " + e.seriesName + ' : ' + (e.value[1]/1000/1000).toFixed(2) + multiParams.unit + '
'
+ } else {
+ res += e.marker +" " + e.seriesName + ' : ' + e.value[1] + '
'
+ }
+ })
+ return res;
+ }
+ },
+ legend: {
+ top:"8%",
+ formatter: function (name) {
+ return name;
+ }
+ },
+ xAxis: {
+ type: 'time',
+ axisLabel: {
+ formatter: function(value,index){
+ let datetime = new Date(value*1000)
+ return datetime.getHours().toString()+':'+ datetime.getMinutes().toString()
+ }
+ }
+ },
+ yAxis: {
+ name: multiParams.unit,
+ type: 'value',
+ scale: true,
+ axisLabel: {
+ formatter: function(value,index){
+ if (multiParams.unit == 'MB' && value>0){
+ return value/1000/1000
+ } else {
+ return value
+ }
+ }
+ }
+ },
+ series: [{type : 'line',
+ smooth: true,
+ lineStyle : {
+ color: '#63BAC9',
+ width : 2,
+ type : 'solid',
+ },
+ animationDuration: 2000,
+ animationEasing: 'quadraticOut',
+ name: metricData.metric1.name,
+ data: metricData.metric1.value,
+ areaStyle: {
+ color: '#1D292D',
+ opacity: 0.2
+ },
+ smoothMonotone: 'x',
+ showSymbol: false},
+ {type : 'line',
+ smooth: true,
+ lineStyle : {
+ color: '#B29943',
+ width : 2,
+ type : 'solid',
+ },
+ animationDuration: 2000,
+ animationEasing: 'quadraticOut',
+ name: metricData.metric2.name,
+ data: metricData.metric2.value,
+ areaStyle: {
+ color: '#313830',
+ opacity: 0.2
+ },
+ smoothMonotone: 'x',
+ showSymbol: false},
+ {type : 'line',
+ smooth: true,
+ lineStyle : {
+ color: '#7CA76D',
+ width : 2,
+ type : 'solid',
+ },
+ animationDuration: 2000,
+ animationEasing: 'quadraticOut',
+ name: metricData.metric3.name,
+ data: metricData.metric3.value,
+ areaStyle: {
+ color: '#394437',
+ opacity: 0.2
+ },
+ smoothMonotone: 'x',
+ showSymbol: false}]
+ };
+ multiParamsId.setOption(option);
+}
\ No newline at end of file
diff --git a/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/jvmInfo.html b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/jvmInfo.html
new file mode 100644
index 000000000..b4897d42f
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/jvmInfo.html
@@ -0,0 +1,223 @@
+
+
+
+
+
+
+ ${constants.getSystemName()}
+
+
+
+
+
+
+
+@/* 加入contextPath属性和session超时的配置 */
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/logbackInfo.html b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/logbackInfo.html
new file mode 100644
index 000000000..f1904efe5
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/logbackInfo.html
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+ ${constants.getSystemName()}
+
+
+
+
+
+
+
+@/* 加入contextPath属性和session超时的配置 */
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/performanceInfo.html b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/performanceInfo.html
new file mode 100644
index 000000000..8bf2fe826
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/performanceInfo.html
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+ ${constants.getSystemName()}
+
+
+
+
+
+
+
+@/* 加入contextPath属性和session超时的配置 */
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/tomcatInfo.html b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/tomcatInfo.html
new file mode 100644
index 000000000..b45d0cc25
--- /dev/null
+++ b/kernel-o-monitor/monitor-integration-beetl/src/main/resources/pages/modular/system/monitor/tomcatInfo.html
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+ ${constants.getSystemName()}
+
+
+
+
+
+
+
+ @/* 加入contextPath属性和session超时的配置 */
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/kernel-o-monitor/pom.xml b/kernel-o-monitor/pom.xml
index acf4fb0e4..1abded52f 100644
--- a/kernel-o-monitor/pom.xml
+++ b/kernel-o-monitor/pom.xml
@@ -17,6 +17,7 @@
monitor-api
+ monitor-integration-beetl
monitor-sdk-system-info
monitor-spring-boot-starter
monitor-sdk-prometheus