From 4690ed876fc2677d648aec128ffb713071e55c0b Mon Sep 17 00:00:00 2001 From: bwcx_jzy Date: Sun, 23 Jan 2022 14:40:06 +0800 Subject: [PATCH] fix --- PLANS.md | 4 +- .../node/NodeWelcomeController.java | 126 +++++++------ .../io/jpom/model/log/SystemMonitorLog.java | 13 ++ .../java/io/jpom/monitor/NodeMonitor.java | 10 +- .../src/main/resources/sql/h2-db-v1.1.sql | 3 + web-vue/src/api/node-stat.js | 165 +++++++++++++----- web-vue/src/api/node.js | 24 +-- .../src/pages/node/node-layout/node-top.vue | 42 +++-- .../src/pages/node/node-layout/welcome.vue | 22 +-- web-vue/src/pages/node/stat.vue | 56 +++--- 10 files changed, 283 insertions(+), 182 deletions(-) diff --git a/PLANS.md b/PLANS.md index 7670def19..0b35afe0b 100644 --- a/PLANS.md +++ b/PLANS.md @@ -14,9 +14,9 @@ 8. h2 数据库升级 2.0 9. 容器构建 10. docker ui -11. 节点大屏 +11. ~~节点大屏~~ 12. ~~实时阅读日志文件~~ -13. 配置分发 +13. ~~配置分发~~ # 2.7.x diff --git a/modules/server/src/main/java/io/jpom/controller/node/NodeWelcomeController.java b/modules/server/src/main/java/io/jpom/controller/node/NodeWelcomeController.java index 398e004d9..347c796c1 100644 --- a/modules/server/src/main/java/io/jpom/controller/node/NodeWelcomeController.java +++ b/modules/server/src/main/java/io/jpom/controller/node/NodeWelcomeController.java @@ -1,18 +1,13 @@ package io.jpom.controller.node; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.db.Entity; import cn.hutool.db.Page; import cn.hutool.db.sql.Direction; import cn.hutool.db.sql.Order; -import cn.hutool.extra.servlet.ServletUtil; import cn.jiangzeyin.common.JsonMessage; -import com.alibaba.fastjson.JSONObject; import io.jpom.common.BaseServerController; import io.jpom.common.forward.NodeForward; import io.jpom.common.forward.NodeUrl; @@ -22,13 +17,11 @@ import io.jpom.permission.SystemPermission; import io.jpom.service.dblog.DbSystemMonitorLogService; import org.springframework.http.MediaType; import org.springframework.util.Assert; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; -import javax.servlet.http.HttpServletResponse; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.List; /** @@ -46,10 +39,11 @@ public class NodeWelcomeController extends BaseServerController { this.dbSystemMonitorLogService = dbSystemMonitorLogService; } - @PostMapping(value = "nodeMonitor_data.json", produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "node_monitor_data.json", produces = MediaType.APPLICATION_JSON_VALUE) public String nodeMonitorJson() { - JSONObject object = getData(); - return JsonMessage.getString(200, "ok", object); + List list = this.getList(); + Assert.notEmpty(list, "没有查询到任何数据"); + return JsonMessage.getString(200, "ok", list); } private List getList() { @@ -59,7 +53,7 @@ public class NodeWelcomeController extends BaseServerController { if (StrUtil.hasEmpty(startDateStr, endDateStr)) { SystemMonitorLog systemMonitorLog = new SystemMonitorLog(); systemMonitorLog.setNodeId(node.getId()); - return dbSystemMonitorLogService.queryList(systemMonitorLog, 100, new Order("monitorTime", Direction.DESC)); + return dbSystemMonitorLogService.queryList(systemMonitorLog, 500, new Order("monitorTime", Direction.DESC)); } // 处理时间 DateTime startDate = DateUtil.parse(startDateStr); @@ -72,7 +66,7 @@ public class NodeWelcomeController extends BaseServerController { long endTime = endDate.getTime(); // 开启了节点信息采集 - Page pageObj = new Page(1, 2000); + Page pageObj = new Page(1, 5000); pageObj.addOrder(new Order("monitorTime", Direction.DESC)); Entity entity = Entity.create(); entity.set("nodeId", node.getId()); @@ -81,57 +75,57 @@ public class NodeWelcomeController extends BaseServerController { return dbSystemMonitorLogService.listPageOnlyResult(entity, pageObj); } - private JSONObject getData() { - List list = getList(); - Assert.notEmpty(list, "没有查询到任何数据"); - List series = new ArrayList<>(); - List scale = new ArrayList<>(); - for (int i = list.size() - 1; i >= 0; i--) { - SystemMonitorLog systemMonitorLog = list.get(i); - scale.add(new DateTime(systemMonitorLog.getMonitorTime()).toString(DatePattern.NORM_DATETIME_PATTERN)); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("cpu", systemMonitorLog.getOccupyCpu()); - jsonObject.put("memory", systemMonitorLog.getOccupyMemory()); - jsonObject.put("memoryUsed", systemMonitorLog.getOccupyMemoryUsed()); - jsonObject.put("disk", systemMonitorLog.getOccupyDisk()); - series.add(jsonObject); - } +// private JSONObject getData() { +// List list = getList(); +// Assert.notEmpty(list, "没有查询到任何数据"); +// List series = new ArrayList<>(); +// List scale = new ArrayList<>(); +// for (int i = list.size() - 1; i >= 0; i--) { +// SystemMonitorLog systemMonitorLog = list.get(i); +// scale.add(new DateTime(systemMonitorLog.getMonitorTime()).toString(DatePattern.NORM_DATETIME_PATTERN)); +// JSONObject jsonObject = new JSONObject(); +// jsonObject.put("cpu", systemMonitorLog.getOccupyCpu()); +// jsonObject.put("memory", systemMonitorLog.getOccupyMemory()); +// jsonObject.put("memoryUsed", systemMonitorLog.getOccupyMemoryUsed()); +// jsonObject.put("disk", systemMonitorLog.getOccupyDisk()); +// series.add(jsonObject); +// } +// +// JSONObject object = new JSONObject(); +// object.put("scales", scale); +// object.put("series", series); +// return object; +// } +// +// @PostMapping(value = "getTop", produces = MediaType.APPLICATION_JSON_VALUE) +// public String getTop() { +// JSONObject object = getData(); +// return JsonMessage.getString(200, "ok", object); +// } - JSONObject object = new JSONObject(); - object.put("scales", scale); - object.put("series", series); - return object; - } - - @PostMapping(value = "getTop", produces = MediaType.APPLICATION_JSON_VALUE) - public String getTop() { - JSONObject object = getData(); - return JsonMessage.getString(200, "ok", object); - } - - @RequestMapping(value = "exportTop") - public void exportTop(String time) throws UnsupportedEncodingException { - List result = getList(); - if (CollUtil.isEmpty(result)) { - // NodeForward.requestDownload(node, getRequest(), getResponse(), NodeUrl.exportTop); - } else { - NodeModel node = getNode(); - StringBuilder buf = new StringBuilder(); - buf.append("监控时间").append(",占用cpu").append(",占用内存").append(",占用磁盘").append("\r\n"); - for (SystemMonitorLog log : result) { - long monitorTime = log.getMonitorTime(); - buf.append(DateUtil.date(monitorTime)).append(StrUtil.COMMA) - .append(log.getOccupyCpu()).append("%").append(StrUtil.COMMA) - .append(log.getOccupyMemory()).append("%").append(StrUtil.COMMA) - .append(log.getOccupyDisk()).append("%").append("\r\n"); - } - String fileName = URLEncoder.encode("Jpom系统监控-" + node.getId(), "UTF-8"); - HttpServletResponse response = getResponse(); - response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "GBK") + ".csv"); - response.setContentType("text/csv;charset=utf-8"); - ServletUtil.write(getResponse(), buf.toString(), CharsetUtil.UTF_8); - } - } +// @RequestMapping(value = "exportTop") +// public void exportTop(String time) throws UnsupportedEncodingException { +// List result = getList(); +// if (CollUtil.isEmpty(result)) { +// // NodeForward.requestDownload(node, getRequest(), getResponse(), NodeUrl.exportTop); +// } else { +// NodeModel node = getNode(); +// StringBuilder buf = new StringBuilder(); +// buf.append("监控时间").append(",占用cpu").append(",占用内存").append(",占用磁盘").append("\r\n"); +// for (SystemMonitorLog log : result) { +// long monitorTime = log.getMonitorTime(); +// buf.append(DateUtil.date(monitorTime)).append(StrUtil.COMMA) +// .append(log.getOccupyCpu()).append("%").append(StrUtil.COMMA) +// .append(log.getOccupyMemory()).append("%").append(StrUtil.COMMA) +// .append(log.getOccupyDisk()).append("%").append("\r\n"); +// } +// String fileName = URLEncoder.encode("Jpom系统监控-" + node.getId(), "UTF-8"); +// HttpServletResponse response = getResponse(); +// response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "GBK") + ".csv"); +// response.setContentType("text/csv;charset=utf-8"); +// ServletUtil.write(getResponse(), buf.toString(), CharsetUtil.UTF_8); +// } +// } @RequestMapping(value = "processList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) public String getProcessList() { diff --git a/modules/server/src/main/java/io/jpom/model/log/SystemMonitorLog.java b/modules/server/src/main/java/io/jpom/model/log/SystemMonitorLog.java index 68796918a..dd8729b0e 100644 --- a/modules/server/src/main/java/io/jpom/model/log/SystemMonitorLog.java +++ b/modules/server/src/main/java/io/jpom/model/log/SystemMonitorLog.java @@ -40,6 +40,7 @@ public class SystemMonitorLog extends BaseDbModel { private String nodeId; /** * 监控时间 + * 插件端返回的时间 */ private Long monitorTime; /** @@ -58,6 +59,18 @@ public class SystemMonitorLog extends BaseDbModel { * 占用磁盘 */ private Double occupyDisk; + /** + * 网络时间 + */ + private Integer networkTime; + + public Integer getNetworkTime() { + return networkTime; + } + + public void setNetworkTime(Integer networkTime) { + this.networkTime = networkTime; + } public String getNodeId() { return nodeId; diff --git a/modules/server/src/main/java/io/jpom/monitor/NodeMonitor.java b/modules/server/src/main/java/io/jpom/monitor/NodeMonitor.java index 0af1c7df8..c456dca33 100644 --- a/modules/server/src/main/java/io/jpom/monitor/NodeMonitor.java +++ b/modules/server/src/main/java/io/jpom/monitor/NodeMonitor.java @@ -130,16 +130,17 @@ public class NodeMonitor { JSONObject jsonObject; if (jsonMessage.getCode() == 200) { jsonObject = jsonMessage.getData(JSONObject.class); - jsonObject.put("networkTime", networkTime); - this.save(modelList, nodeTopInfo, jsonObject); } else { // 状态码错 jsonObject = new JSONObject(); jsonObject.put("status", 3); jsonObject.put("failureMsg", jsonMessage.toString()); - jsonObject.put("networkTime", networkTime); - this.save(modelList, nodeTopInfo, jsonObject); } + jsonObject.put("networkTime", networkTime); + if (nodeTopInfo != null) { + nodeTopInfo.put("networkTime", networkTime); + } + this.save(modelList, nodeTopInfo, jsonObject); } catch (AuthorizeException agentException) { this.save(modelList, 2, agentException.getMessage()); } catch (Exception e) { @@ -161,6 +162,7 @@ public class NodeMonitor { log.setOccupyDisk(systemMonitor.getDouble("disk")); log.setOccupyCpu(systemMonitor.getDouble("cpu")); log.setMonitorTime(systemMonitor.getLongValue("time")); + log.setNetworkTime(systemMonitor.getIntValue("networkTime")); log.setNodeId(nodeModel.getId()); return log; }).collect(Collectors.toList()); diff --git a/modules/sub-plugin/db-h2/src/main/resources/sql/h2-db-v1.1.sql b/modules/sub-plugin/db-h2/src/main/resources/sql/h2-db-v1.1.sql index 9c329951c..ba137a834 100644 --- a/modules/sub-plugin/db-h2/src/main/resources/sql/h2-db-v1.1.sql +++ b/modules/sub-plugin/db-h2/src/main/resources/sql/h2-db-v1.1.sql @@ -21,3 +21,6 @@ ALTER TABLE BUILDHISTORYLOG ALTER TABLE SSHTERMINALEXECUTELOG ALTER COLUMN commands CLOB comment '操作的命令'; + +ALTER TABLE SYSTEMMONITORLOG + ADD IF NOT EXISTS networkTime int COMMENT '延迟时间ms'; diff --git a/web-vue/src/api/node-stat.js b/web-vue/src/api/node-stat.js index ea8479000..f28c62815 100644 --- a/web-vue/src/api/node-stat.js +++ b/web-vue/src/api/node-stat.js @@ -1,4 +1,6 @@ import axios from "./config"; +import { parseTime } from "@/utils/time"; +import echarts from "echarts"; // node 列表 export function getStatist(params) { @@ -23,8 +25,48 @@ export function statusStat() { }); } -export function generateChart(data) { - let cpuItem = { +const defaultData = { + title: { + // text: "系统 Top 监控", + }, + tooltip: { + trigger: "axis", + }, + legend: { + // data: legends, + }, + color: ["#5470c6", "#91cc75", "#fac858", "#ee6666", "#73c0de", "#3ba272", "#fc8452", "#9a60b4", "#ea7ccc"], + grid: { + left: "1%", + right: "2%", + bottom: "1%", + containLabel: true, + }, + xAxis: { + type: "category", + boundaryGap: false, + // data: scales, + }, + calculable: true, + // yAxis: { + // type: "value", + // axisLabel: { + // // 设置y轴数值为% + // formatter: "{value} %", + // }, + // max: 100, + // }, + dataZoom: [{ type: "inside" }, { type: "slider" }], + // series: series, +}; + +/** + * 节点系统统计 + * @param { JSON } data + * @returns + */ +export function generateNodeTopChart(data) { + const cpuItem = { name: "cpu占用", type: "line", data: [], @@ -32,65 +74,55 @@ export function generateChart(data) { // 设置折线为曲线 smooth: true, }; - let diskItem = { + const diskItem = { name: "磁盘占用", type: "line", data: [], showSymbol: false, smooth: true, }; - let memoryItem = { + const memoryItem = { name: "内存占用(累计)", type: "line", data: [], showSymbol: false, smooth: true, }; - let memoryUsedItem = { + const memoryUsedItem = { name: "内存占用", type: "line", data: [], showSymbol: false, smooth: true, }; - data.series.forEach((item) => { - cpuItem.data.push(parseFloat(item.cpu)); - diskItem.data.push(parseFloat(item.disk)); - memoryItem.data.push(parseFloat(item.memory)); - if (item.memoryUsed) { - memoryUsedItem.data.push(parseFloat(item.memoryUsed)); + const scales = []; + for (var i = data.length - 1; i >= 0; i--) { + const item = data[i]; + cpuItem.data.push(parseFloat(item.occupyCpu)); + diskItem.data.push(parseFloat(item.occupyDisk)); + memoryItem.data.push(parseFloat(item.occupyMemory)); + if (item.occupyMemoryUsed) { + memoryUsedItem.data.push(parseFloat(item.occupyMemoryUsed)); } - }); - let series = [cpuItem, memoryItem, diskItem]; + scales.push(parseTime(item.monitorTime)); + } + + const series = [cpuItem, memoryItem, diskItem]; if (memoryUsedItem.data.length > 0) { series.push(memoryUsedItem); } - let legends = series.map((data) => { + const legends = series.map((data) => { return data.name; }); + // 指定图表的配置项和数据 - return { - title: { - text: "系统 Top 监控", - }, - tooltip: { - trigger: "axis", - }, + return Object.assign({}, defaultData, { legend: { data: legends, }, - grid: { - left: "1%", - right: "2%", - bottom: "1%", - containLabel: true, - }, xAxis: { - type: "category", - boundaryGap: false, - data: data.scales, + data: scales, }, - calculable: true, yAxis: { type: "value", axisLabel: { @@ -99,9 +131,70 @@ export function generateChart(data) { }, max: 100, }, - dataZoom: [{ type: "inside" }, { type: "slider" }], series: series, + }); +} + +/** + * 节点网络延迟 + * @param { JSON } data + * @returns + */ +export function generateNodeNetworkTimeChart(data) { + const dataArray = { + name: "网络延迟ms", + type: "line", + data: [], + showSymbol: false, + // 设置折线为曲线 + smooth: true, }; + const scales = []; + for (var i = data.length - 1; i >= 0; i--) { + const item = data[i]; + dataArray.data.push(parseFloat(item.networkTime)); + scales.push(parseTime(item.monitorTime)); + } + + const series = [dataArray]; + + const legends = series.map((data) => { + return data.name; + }); + // 指定图表的配置项和数据 + return Object.assign({}, defaultData, { + legend: { + data: legends, + }, + xAxis: { + data: scales, + }, + yAxis: { + type: "value", + axisLabel: { + formatter: "{value} ms", + }, + }, + series: series, + }); +} + +/** + * + * @param {*} data + * @param {String} domId + * @returns + */ +export function drawChart(data, domId, parseFn) { + const historyChartDom = document.getElementById(domId, domId); + if (!historyChartDom) { + return; + } + const option = parseFn(data); + + // 绘制图表 + const historyChart = echarts.init(historyChartDom); + historyChart.setOption(option); } export const status = { @@ -110,11 +203,3 @@ export const status = { 2: "授权信息错误", 3: "状态码错误", }; - -// export const nodeMonitorCycle = { -// "-30": "30 秒", -// 1: "1 分钟", -// 5: "5 分钟", -// 10: "10 分钟", -// 30: "30 分钟", -// }; diff --git a/web-vue/src/api/node.js b/web-vue/src/api/node.js index e1390bc2f..409b7b2d3 100644 --- a/web-vue/src/api/node.js +++ b/web-vue/src/api/node.js @@ -144,17 +144,17 @@ export function deleteNode(id) { }); } -// 节点 top 命令 -export function getNodeTop(nodeId) { - return axios({ - url: "/node/getTop", - method: "post", - data: { nodeId }, - headers: { - loading: "no", - }, - }); -} +// // 节点 top 命令 +// export function getNodeTop(nodeId) { +// return axios({ +// url: "/node/getTop", +// method: "post", +// data: { nodeId }, +// headers: { +// loading: "no", +// }, +// }); +// } // 获取进程列表 export function getProcessList(data) { @@ -189,7 +189,7 @@ export function killPid(params) { */ export function nodeMonitorData(params) { return axios({ - url: "/node/nodeMonitor_data.json", + url: "/node/node_monitor_data.json", method: "post", data: params, }); diff --git a/web-vue/src/pages/node/node-layout/node-top.vue b/web-vue/src/pages/node/node-layout/node-top.vue index 42aa58b26..6962328c7 100644 --- a/web-vue/src/pages/node/node-layout/node-top.vue +++ b/web-vue/src/pages/node/node-layout/node-top.vue @@ -2,7 +2,19 @@
- + 搜索
@@ -11,15 +23,17 @@ diff --git a/web-vue/src/pages/node/node-layout/welcome.vue b/web-vue/src/pages/node/node-layout/welcome.vue index c266f0814..cd63c62a7 100644 --- a/web-vue/src/pages/node/node-layout/welcome.vue +++ b/web-vue/src/pages/node/node-layout/welcome.vue @@ -52,11 +52,11 @@