mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 20:08:40 +08:00
监控缓存
This commit is contained in:
parent
b2383f32ce
commit
02e5903f45
@ -4,6 +4,7 @@ import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.jiangzeyin.controller.base.AbstractController;
|
||||
import cn.keepbx.jpom.common.commander.AbstractSystemCommander;
|
||||
import cn.keepbx.jpom.model.system.ProcessModel;
|
||||
import cn.keepbx.jpom.system.TopManager;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@ -22,7 +23,7 @@ public class WelcomeController extends AbstractController {
|
||||
|
||||
@RequestMapping(value = "getTop", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String getTop() {
|
||||
JSONObject topInfo = AbstractSystemCommander.getInstance().getAllMonitor();
|
||||
JSONObject topInfo = TopManager.getTopMonitor();
|
||||
return JsonMessage.getString(200, "", topInfo);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
package cn.keepbx.jpom.system;
|
||||
|
||||
import cn.hutool.cache.impl.CacheObj;
|
||||
import cn.hutool.cache.impl.TimedCache;
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.cron.CronUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.pool.ThreadPoolService;
|
||||
@ -13,11 +17,9 @@ import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
@ -31,6 +33,8 @@ public class TopManager {
|
||||
private static final Set<Session> SESSIONS = new HashSet<>();
|
||||
private static final String CRON_ID = "topMonitor";
|
||||
private static ExecutorService executorService = ThreadPoolService.newCachedThreadPool(TopManager.class);
|
||||
private static final TimedCache<String, JSONObject> MONITOR_CACHE = new TimedCache<>(TimeUnit.MINUTES.toMillis(12), new LinkedHashMap<>());
|
||||
|
||||
/**
|
||||
* 是否开启首页监听(自动刷新)
|
||||
*/
|
||||
@ -69,15 +73,9 @@ public class TopManager {
|
||||
try {
|
||||
JSONObject topInfo = AbstractSystemCommander.getInstance().getAllMonitor();
|
||||
if (topInfo != null) {
|
||||
DateTime date = DateUtil.date();
|
||||
int hour = date.hour(true);
|
||||
int minute = date.minute();
|
||||
int day = date.dayOfMonth();
|
||||
topInfo.put("hour", hour);
|
||||
topInfo.put("minute", minute);
|
||||
topInfo.put("day", day);
|
||||
topInfo.put("second", date.second());
|
||||
topInfo.put("time", DateUtil.format(date, "HH:mm:ss"));
|
||||
String time = DateUtil.formatTime(DateUtil.date());
|
||||
topInfo.put("time", time);
|
||||
MONITOR_CACHE.put(time, topInfo);
|
||||
send(topInfo.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -90,6 +88,66 @@ public class TopManager {
|
||||
WATCH.set(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存的监控信息
|
||||
*
|
||||
* @return 监控信息
|
||||
*/
|
||||
public static JSONObject getTopMonitor() {
|
||||
Iterator<CacheObj<String, JSONObject>> cacheObjIterator = MONITOR_CACHE.cacheObjIterator();
|
||||
String lastTime = "";
|
||||
List<JSONObject> array = new ArrayList<>();
|
||||
List<String> scale = new ArrayList<>();
|
||||
while (cacheObjIterator.hasNext()) {
|
||||
CacheObj<String, JSONObject> cacheObj = cacheObjIterator.next();
|
||||
String key = cacheObj.getKey();
|
||||
if (StrUtil.isNotEmpty(lastTime)) {
|
||||
if (!key.equals(getLastTime(lastTime))) {
|
||||
array.clear();
|
||||
scale.clear();
|
||||
}
|
||||
}
|
||||
lastTime = key;
|
||||
scale.add(key);
|
||||
JSONObject value = cacheObj.getValue();
|
||||
array.add(value);
|
||||
}
|
||||
int count = 24;
|
||||
if (array.size() > count) {
|
||||
array = array.subList(array.size() - count - 1, array.size() - 1);
|
||||
}
|
||||
while (scale.size() < count) {
|
||||
if (scale.size() == 0) {
|
||||
DateTime date = DateUtil.date();
|
||||
int second = date.second();
|
||||
if (second <= 30 && second > 0) {
|
||||
second = 30;
|
||||
} else if (second > 30) {
|
||||
second = 0;
|
||||
date = date.offset(DateField.MINUTE, 1);
|
||||
}
|
||||
String format = DateUtil.format(date, "HH:mm");
|
||||
String secondStr = ":" + second;
|
||||
if (second < 10) {
|
||||
secondStr = ":0" + second;
|
||||
}
|
||||
scale.add(format + secondStr);
|
||||
}
|
||||
String time = scale.get(scale.size() - 1);
|
||||
String newTime = getLastTime(time);
|
||||
scale.add(newTime);
|
||||
}
|
||||
JSONObject object = new JSONObject();
|
||||
object.put("scale", scale);
|
||||
object.put("series", array);
|
||||
return object;
|
||||
}
|
||||
|
||||
private static String getLastTime(String time) {
|
||||
DateTime dateTime = DateUtil.parseTime(time);
|
||||
DateTime newTime = dateTime.offsetNew(DateField.SECOND, 30);
|
||||
return DateUtil.formatTime(newTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送首页进程列表信息
|
||||
|
@ -51,228 +51,171 @@
|
||||
};
|
||||
|
||||
function loadSuccess() {
|
||||
//
|
||||
loadTopData();
|
||||
loadTop();
|
||||
//加载进程信息
|
||||
loadProcessList();
|
||||
//
|
||||
tableRender(config);
|
||||
linkSocket(true);
|
||||
}
|
||||
|
||||
//加载病状图
|
||||
function loadEcharts(xAxis, series) {
|
||||
if (!series) {
|
||||
return;
|
||||
function loadTop() {
|
||||
silentAjax({
|
||||
url: './getTop',
|
||||
success: function (data) {
|
||||
if (200 === data.code && data.data) {
|
||||
loadEchartsData(data.data);
|
||||
//打开socket
|
||||
linkSocket(true);
|
||||
}
|
||||
}
|
||||
let option = {
|
||||
title: {
|
||||
text: '系统监控'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['cpu占用', '内存占用', '磁盘占用'],
|
||||
right: '1%'
|
||||
},
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
bottom: '1%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: xAxis
|
||||
},
|
||||
calculable: true,
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
//设置y轴数值为%
|
||||
formatter: '{value} %'
|
||||
},
|
||||
max: 100
|
||||
},
|
||||
series: series
|
||||
};
|
||||
if (!myEcharts) {
|
||||
myEcharts = echarts.init(document.getElementById('echarts'));
|
||||
});
|
||||
}
|
||||
|
||||
function loadEchartsData(data) {
|
||||
let series = data.series;
|
||||
let cpuItem = {
|
||||
name: 'cpu占用',
|
||||
type: 'line',
|
||||
data: [0],
|
||||
//设置折线为曲线
|
||||
smooth: true
|
||||
};
|
||||
let diskItem = {
|
||||
name: '磁盘占用',
|
||||
type: 'line',
|
||||
data: [0],
|
||||
smooth: true
|
||||
};
|
||||
let memoryItem = {
|
||||
name: '内存占用',
|
||||
type: 'line',
|
||||
data: [0],
|
||||
smooth: true
|
||||
};
|
||||
for (let i = 0; i < series.length; i++) {
|
||||
let item = series[i];
|
||||
if (i === 0) {
|
||||
//删除默认0的数据
|
||||
cpuItem.data.splice(0, 1);
|
||||
diskItem.data.splice(0, 1);
|
||||
memoryItem.data.splice(0, 1);
|
||||
}
|
||||
myEcharts.setOption(option);
|
||||
cpuItem.data.push(parseFloat(item.cpu));
|
||||
diskItem.data.push(parseFloat(item.disk));
|
||||
memoryItem.data.push(parseFloat(item.memory));
|
||||
}
|
||||
let array = [cpuItem, memoryItem, diskItem];
|
||||
loadEcharts(data.scale, array);
|
||||
}
|
||||
|
||||
function linkSocket(status) {
|
||||
if (!('WebSocket' in window)) {
|
||||
layer.msg("不支持WebSocket");
|
||||
return;
|
||||
}
|
||||
var url = getSocketHost() + "/console?userId=[[${session.user.getUserMd5Key()}]]&projectId=system&nodeId=[[${node.id}]]&type=console";
|
||||
if (!ws) {
|
||||
//拼接监控数据
|
||||
function addTopData(topData) {
|
||||
let option = myEcharts.getOption();
|
||||
let series = option.series;
|
||||
let xAxis = option.xAxis;
|
||||
let xAxisData = xAxis[0].data;
|
||||
|
||||
let cpuItem = series[0];
|
||||
let memoryItem = series[1];
|
||||
let diskItem = series[2];
|
||||
cpuItem.data.push(parseFloat(topData.cpu));
|
||||
diskItem.data.push(parseFloat(topData.disk));
|
||||
memoryItem.data.push(parseFloat(topData.memory));
|
||||
//删除过时数据
|
||||
if (cpuItem.data.length > xAxisData.length) {
|
||||
cpuItem.data.splice(0, 1);
|
||||
diskItem.data.splice(0, 1);
|
||||
memoryItem.data.splice(0, 1);
|
||||
xAxisData.splice(0, 1);
|
||||
xAxisData.push(topData.time);
|
||||
}
|
||||
let newSeries = [cpuItem, memoryItem, diskItem];
|
||||
loadEcharts(xAxisData, newSeries);
|
||||
}
|
||||
|
||||
function linkSocket(status) {
|
||||
if (!('WebSocket' in window)) {
|
||||
layer.msg("不支持WebSocket");
|
||||
return;
|
||||
}
|
||||
var url = getSocketHost() + "/console?userId=[[${session.user.getUserMd5Key()}]]&projectId=system&nodeId=[[${node.id}]]&type=console";
|
||||
if (!ws) {
|
||||
ws = new WebSocket(url);
|
||||
}
|
||||
if (status) {
|
||||
if (ws.readyState !== 1 && ws.readyState !== 0) {
|
||||
ws = new WebSocket(url);
|
||||
}
|
||||
if (status) {
|
||||
if (ws.readyState !== 1 && ws.readyState !== 0) {
|
||||
ws = new WebSocket(url);
|
||||
}
|
||||
ws.onopen = function () {
|
||||
ws.send('{"op": "top", "projectInfo":{}}');
|
||||
};
|
||||
ws.onmessage = function (data) {
|
||||
try {
|
||||
if (data.data) {
|
||||
var top = JSON.parse(data.data);
|
||||
if (top.top) {
|
||||
loadTopData(top);
|
||||
}
|
||||
if (top.processList) {
|
||||
config.data = top.processList;
|
||||
tableRender(config);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
ws.onerror = function (ev) {
|
||||
console.log(ev);
|
||||
layer.msg("socket 异常");
|
||||
}
|
||||
} else {
|
||||
ws.close();
|
||||
}
|
||||
}
|
||||
|
||||
//保存监控数据
|
||||
function loadTopData(topData) {
|
||||
//默认刻度数量
|
||||
let count = 24;
|
||||
let dataTop = layui.data('top_[[${node.id}]]');
|
||||
let top = [];
|
||||
if (dataTop && dataTop.top) {
|
||||
top = dataTop.top;
|
||||
}
|
||||
if (topData) {
|
||||
top.push(topData);
|
||||
}
|
||||
let array = [];
|
||||
let xAxis = [];
|
||||
let cpuItem = {
|
||||
name: 'cpu占用',
|
||||
type: 'line',
|
||||
data: [0],
|
||||
//设置折线为曲线
|
||||
smooth: true
|
||||
ws.onopen = function () {
|
||||
ws.send('{"op": "top", "projectInfo":{}}');
|
||||
};
|
||||
let diskItem = {
|
||||
name: '磁盘占用',
|
||||
type: 'line',
|
||||
data: [0],
|
||||
smooth: true
|
||||
ws.onmessage = function (data) {
|
||||
try {
|
||||
if (data.data) {
|
||||
var top = JSON.parse(data.data);
|
||||
if (top.top) {
|
||||
addTopData(top);
|
||||
}
|
||||
if (top.processList) {
|
||||
config.data = top.processList;
|
||||
tableRender(config);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let memoryItem = {
|
||||
name: '内存占用',
|
||||
type: 'line',
|
||||
data: [0],
|
||||
smooth: true
|
||||
};
|
||||
let topLen = top.length;
|
||||
for (let i = topLen - 1; i >= 0; i--) {
|
||||
let item = top[i];
|
||||
let len = array.length;
|
||||
if (len >= count) {
|
||||
break;
|
||||
} else if (len > 0) {
|
||||
let nextItem = array[0];
|
||||
if (nextItem.day !== item.day || nextItem.time !== getNextMinute(item.hour, item.minute, item.second)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i === topLen - 1) {
|
||||
//删除默认0的数据
|
||||
cpuItem.data.splice(0, 1);
|
||||
diskItem.data.splice(0, 1);
|
||||
memoryItem.data.splice(0, 1);
|
||||
}
|
||||
array.splice(0, 0, item);
|
||||
cpuItem.data.splice(0, 0, parseFloat(item.cpu));
|
||||
diskItem.data.splice(0, 0, parseFloat(item.disk));
|
||||
memoryItem.data.splice(0, 0, parseFloat(item.memory));
|
||||
xAxis.splice(0, 0, item.time);
|
||||
ws.onerror = function (ev) {
|
||||
console.log(ev);
|
||||
layer.msg("socket 异常");
|
||||
}
|
||||
let len = xAxis.length;
|
||||
if (len <= count) {
|
||||
let item = array[array.length - 1];
|
||||
if (!item) {
|
||||
var myDate = new Date(); //实例一个时间对象;
|
||||
item = {
|
||||
hour: myDate.getHours(),
|
||||
minute: myDate.getMinutes(),
|
||||
second: myDate.getSeconds()
|
||||
}
|
||||
}
|
||||
let hour = item.hour;
|
||||
let minute = item.minute;
|
||||
let second = item.second;
|
||||
for (let i = 0; i < count - len; i++) {
|
||||
if (i !== 0) {
|
||||
second += 30;
|
||||
if (second >= 60) {
|
||||
second = 0;
|
||||
minute += 1;
|
||||
}
|
||||
if (minute === 60) {
|
||||
minute = 0;
|
||||
hour += 1;
|
||||
}
|
||||
if (hour === 24) {
|
||||
hour = 0;
|
||||
}
|
||||
}
|
||||
xAxis.push(getNextMinute(hour, minute, second));
|
||||
}
|
||||
}
|
||||
let series = [cpuItem, memoryItem, diskItem];
|
||||
loadEcharts(xAxis, series);
|
||||
layui.data('top_[[${node.id}]]', {
|
||||
key: 'top',
|
||||
value: array
|
||||
});
|
||||
} else {
|
||||
ws.close();
|
||||
}
|
||||
}
|
||||
|
||||
//下半分钟 判断时间连续性
|
||||
function getNextMinute(hour, minute, second) {
|
||||
second += 30;
|
||||
if (second <= 30 && second > 0) {
|
||||
second = 30;
|
||||
} else if (second >= 60) {
|
||||
second = 0;
|
||||
minute += 1;
|
||||
} else {
|
||||
second = 30;
|
||||
//加载监控图
|
||||
function loadEcharts(xAxis, series) {
|
||||
if (!series) {
|
||||
return;
|
||||
}
|
||||
if (minute === 60) {
|
||||
hour += 1;
|
||||
minute = 0;
|
||||
let option = {
|
||||
title: {
|
||||
text: '系统监控'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['cpu占用', '内存占用', '磁盘占用'],
|
||||
right: '1%'
|
||||
},
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
bottom: '1%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: xAxis
|
||||
},
|
||||
calculable: true,
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
//设置y轴数值为%
|
||||
formatter: '{value} %'
|
||||
},
|
||||
max: 100
|
||||
},
|
||||
series: series
|
||||
};
|
||||
if (!myEcharts) {
|
||||
myEcharts = echarts.init(document.getElementById('echarts'));
|
||||
}
|
||||
let hourStr = hour;
|
||||
let minuteStr = minute;
|
||||
let secondStr = second;
|
||||
if (hour === 24) {
|
||||
hour = 0;
|
||||
}
|
||||
if (hour < 10) {
|
||||
hourStr = "0" + hour;
|
||||
}
|
||||
if (minute < 10) {
|
||||
minuteStr = "0" + minute;
|
||||
}
|
||||
if (second < 10) {
|
||||
secondStr = "0" + second;
|
||||
}
|
||||
return hourStr + ":" + minuteStr + ":" + secondStr;
|
||||
myEcharts.setOption(option);
|
||||
}
|
||||
|
||||
function loadProcessList() {
|
||||
|
Loading…
Reference in New Issue
Block a user