mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-18 23:45:52 +08:00
@@ -110,9 +110,9 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
|
||||
```
|
||||
|
||||
|
||||
### 版本更新 0.16.7
|
||||
### 版本更新 0.16.8
|
||||
|
||||
- mongodb副本设置/备份/认证。
|
||||
- 首页对网络/磁盘IO进行更细致的展示。
|
||||
|
||||
### JSDelivr安装地址
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.16.7'
|
||||
__version = '0.16.8'
|
||||
__api_addr = 'data/api.json'
|
||||
|
||||
# 统一默认配置文件
|
||||
|
||||
+168
-25
@@ -44,10 +44,11 @@ def mw_async(f):
|
||||
class system_api:
|
||||
setupPath = None
|
||||
pids = None
|
||||
|
||||
cache = {}
|
||||
def __init__(self):
|
||||
self.setupPath = mw.getServerDir()
|
||||
|
||||
|
||||
##### ----- start ----- ###
|
||||
def networkApi(self):
|
||||
data = self.getNetWork()
|
||||
@@ -254,8 +255,7 @@ class system_api:
|
||||
data['load_average'] = self.GetLoadAverage(get)
|
||||
data['title'] = self.GetTitle()
|
||||
data['network'] = self.GetNetWorkApi(get)
|
||||
data['panel_status'] = not os.path.exists(
|
||||
'/www/server/mdserver-web/data/close.pl')
|
||||
data['panel_status'] = not os.path.exists('/www/server/mdserver-web/data/close.pl')
|
||||
import firewalls
|
||||
ssh_info = firewalls.firewalls().GetSshInfo(None)
|
||||
data['enable_ssh_status'] = ssh_info['status']
|
||||
@@ -488,7 +488,7 @@ class system_api:
|
||||
shutil.rmtree(filename)
|
||||
else:
|
||||
os.remove(filename)
|
||||
print('mail clear ok')
|
||||
# print('mail clear ok')
|
||||
num += 1
|
||||
total += size
|
||||
count += num
|
||||
@@ -547,38 +547,181 @@ class system_api:
|
||||
def getNetWork(self):
|
||||
# 取网络流量信息
|
||||
try:
|
||||
# 取网络流量信息
|
||||
networkIo = self.psutilNetIoCounters()
|
||||
if not "otime" in session:
|
||||
session['up'] = networkIo[0]
|
||||
session['down'] = networkIo[1]
|
||||
session['otime'] = time.time()
|
||||
|
||||
ntime = time.time()
|
||||
networkInfo = {}
|
||||
networkInfo['upTotal'] = networkIo[0]
|
||||
networkInfo['downTotal'] = networkIo[1]
|
||||
networkInfo['up'] = round(float(
|
||||
networkIo[0] - session['up']) / (ntime - session['otime']), 2)
|
||||
networkInfo['down'] = round(
|
||||
float(networkIo[1] - session['down']) / (ntime - session['otime']), 2)
|
||||
networkInfo['downPackets'] = networkIo[3]
|
||||
networkInfo['upPackets'] = networkIo[2]
|
||||
# 取网络流量信息
|
||||
# networkIo = self.psutilNetIoCounters()
|
||||
# if not "otime" in session:
|
||||
# session['up'] = networkIo[0]
|
||||
# session['down'] = networkIo[1]
|
||||
# session['otime'] = time.time()
|
||||
|
||||
# print networkIo[1], session['down'], ntime, session['otime']
|
||||
session['up'] = networkIo[0]
|
||||
session['down'] = networkIo[1]
|
||||
session['otime'] = time.time()
|
||||
# ntime = time.time()
|
||||
# print("source",ntime - session['otime'])
|
||||
|
||||
# networkInfo['upTotal'] = networkIo[0]
|
||||
# networkInfo['downTotal'] = networkIo[1]
|
||||
# networkInfo['up'] = round(float(
|
||||
# networkIo[0] - session['up']) / (ntime - session['otime']), 2)
|
||||
# networkInfo['down'] = round(
|
||||
# float(networkIo[1] - session['down']) / (ntime - session['otime']), 2)
|
||||
# networkInfo['downPackets'] = networkIo[3]
|
||||
# networkInfo['upPackets'] = networkIo[2]
|
||||
|
||||
# # print networkIo[1], session['down'], ntime, session['otime']
|
||||
# session['up'] = networkIo[0]
|
||||
# session['down'] = networkIo[1]
|
||||
# session['otime'] = time.time()
|
||||
|
||||
networkInfo['cpu'] = self.getCpuInfo()
|
||||
networkInfo['load'] = self.getLoadAverage()
|
||||
networkInfo['mem'] = self.getMemInfo()
|
||||
networkInfo['iostat'] = self.getDiskIostat()
|
||||
networkInfo['network'] = self.getNetWorkIostat()
|
||||
|
||||
return networkInfo
|
||||
except Exception as e:
|
||||
print("getNetWork error:", e)
|
||||
print(mw.getTracebackInfo())
|
||||
return None
|
||||
|
||||
def getNetWorkIostat(self):
|
||||
netInfo = {}
|
||||
|
||||
netInfo['ALL'] = {}
|
||||
netInfo['ALL']['up'] = 0
|
||||
netInfo['ALL']['down'] = 0
|
||||
netInfo['ALL']['upTotal'] = 0
|
||||
netInfo['ALL']['downTotal'] = 0
|
||||
netInfo['ALL']['upPackets'] = 0
|
||||
netInfo['ALL']['downPackets'] = 0
|
||||
|
||||
mtime = time.time()
|
||||
iokey = 'netstat'
|
||||
netio = None
|
||||
if iokey in self.cache:
|
||||
netio = self.cache[iokey]
|
||||
|
||||
if not netio:
|
||||
netio = {}
|
||||
netio['info'] = None
|
||||
netio['all_io'] = None
|
||||
netio['time'] = mtime
|
||||
|
||||
stime = mtime - netio['time']
|
||||
if not stime: stime = 1
|
||||
|
||||
# print("new:",stime)
|
||||
netio_group = psutil.net_io_counters(pernic=True).keys()
|
||||
|
||||
netio_cache = netio['info']
|
||||
allio_cache = netio['all_io']
|
||||
if not netio_cache:
|
||||
netio_cache = {}
|
||||
|
||||
netio_group_t = {}
|
||||
for name in netio_group:
|
||||
netInfo[name] = {}
|
||||
|
||||
io_data = psutil.net_io_counters(pernic=True).get(name)
|
||||
if not name in netio_cache:
|
||||
netio_cache[name] = io_data
|
||||
|
||||
netio_group_t[name] = io_data
|
||||
|
||||
netInfo[name]['up'] = round(float((io_data[0] - netio_cache[name][0]) / stime), 2)
|
||||
netInfo[name]['down'] = round(float((io_data[1] - netio_cache[name][1])/ stime), 2)
|
||||
|
||||
netInfo[name]['upTotal'] = io_data[0]
|
||||
netInfo[name]['downTotal'] = io_data[1]
|
||||
netInfo[name]['upPackets'] = io_data[2]
|
||||
netInfo[name]['downPackets'] = io_data[3]
|
||||
|
||||
all_io = psutil.net_io_counters()[:4]
|
||||
if not allio_cache:
|
||||
allio_cache = all_io
|
||||
|
||||
netInfo['ALL']['up'] = round(float((all_io[0] - allio_cache[0]) /stime), 2)
|
||||
netInfo['ALL']['down'] = round(float((all_io[1] - allio_cache[1]) /stime), 2)
|
||||
netInfo['ALL']['upTotal'] = all_io[0]
|
||||
netInfo['ALL']['downTotal'] = all_io[1]
|
||||
netInfo['ALL']['upPackets'] = all_io[2]
|
||||
netInfo['ALL']['downPackets'] = all_io[3]
|
||||
|
||||
self.cache[iokey] = {'info':netio_group_t,'all_io':all_io,'time':mtime}
|
||||
return netInfo
|
||||
|
||||
|
||||
def getDiskIostat(self):
|
||||
iokey = 'iostat'
|
||||
|
||||
diskInfo = {}
|
||||
diskInfo['ALL'] = {}
|
||||
diskInfo['ALL']['read_count'] = 0
|
||||
diskInfo['ALL']['write_count'] = 0
|
||||
diskInfo['ALL']['read_bytes'] = 0
|
||||
diskInfo['ALL']['write_bytes'] = 0
|
||||
diskInfo['ALL']['read_time'] = 0
|
||||
diskInfo['ALL']['write_time'] = 0
|
||||
diskInfo['ALL']['read_merged_count'] = 0
|
||||
diskInfo['ALL']['write_merged_count'] = 0
|
||||
|
||||
try:
|
||||
diskio = None
|
||||
if iokey in self.cache:
|
||||
diskio = self.cache[iokey]
|
||||
|
||||
mtime = int(time.time())
|
||||
if not diskio:
|
||||
diskio = {}
|
||||
diskio['info'] = None
|
||||
diskio['time'] = mtime
|
||||
|
||||
diskio_cache = diskio['info']
|
||||
stime = mtime - diskio['time']
|
||||
if not stime: stime = 1
|
||||
|
||||
diskio_group = psutil.disk_io_counters(perdisk=True)
|
||||
if not diskio_cache:
|
||||
diskio_cache = diskio_group
|
||||
|
||||
for disk_name in diskio_group.keys():
|
||||
diskInfo[disk_name] = {}
|
||||
# print('disk_name',disk_name)
|
||||
# print('diskio_group',diskio_group[disk_name])
|
||||
# print('diskio_cache',diskio_cache[disk_name])
|
||||
|
||||
diskInfo[disk_name]['read_count'] = int((diskio_group[disk_name].read_count - diskio_cache[disk_name].read_count) / stime)
|
||||
diskInfo[disk_name]['write_count'] = int((diskio_group[disk_name].write_count - diskio_cache[disk_name].write_count) / stime)
|
||||
diskInfo[disk_name]['read_bytes'] = int((diskio_group[disk_name].read_bytes - diskio_cache[disk_name].read_bytes) / stime)
|
||||
diskInfo[disk_name]['write_bytes'] = int((diskio_group[disk_name].write_bytes - diskio_cache[disk_name].write_bytes) / stime)
|
||||
diskInfo[disk_name]['read_time'] = int((diskio_group[disk_name].read_time - diskio_cache[disk_name].read_time) / stime)
|
||||
diskInfo[disk_name]['write_time'] = int((diskio_group[disk_name].write_time - diskio_cache[disk_name].write_time) / stime)
|
||||
|
||||
if 'read_merged_count' in diskio_group[disk_name] and 'read_merged_count' in diskio_cache[disk_name]:
|
||||
diskInfo[disk_name]['read_merged_count'] = int((diskio_group[disk_name].read_merged_count - diskio_cache[disk_name].read_merged_count) / stime)
|
||||
if 'write_merged_count' in diskio_group[disk_name] and 'write_merged_count' in diskio_cache[disk_name]:
|
||||
diskInfo[disk_name]['write_merged_count'] = int((diskio_group[disk_name].write_merged_count - diskio_cache[disk_name].write_merged_count) / stime)
|
||||
|
||||
diskInfo['ALL']['read_count'] += diskInfo[disk_name]['read_count']
|
||||
diskInfo['ALL']['write_count'] += diskInfo[disk_name]['write_count']
|
||||
diskInfo['ALL']['read_bytes'] += diskInfo[disk_name]['read_bytes']
|
||||
diskInfo['ALL']['write_bytes'] += diskInfo[disk_name]['write_bytes']
|
||||
if diskInfo['ALL']['read_time'] < diskInfo[disk_name]['read_time']:
|
||||
diskInfo['ALL']['read_time'] = diskInfo[disk_name]['read_time']
|
||||
if diskInfo['ALL']['write_time'] < diskInfo[disk_name]['write_time']:
|
||||
diskInfo['ALL']['write_time'] = diskInfo[disk_name]['write_time']
|
||||
|
||||
if 'read_merged_count' in diskInfo[disk_name] and 'read_merged_count' in diskInfo[disk_name]:
|
||||
diskInfo['ALL']['read_merged_count'] += diskInfo[disk_name]['read_merged_count']
|
||||
if 'write_merged_count' in diskInfo[disk_name] and 'write_merged_count' in diskInfo[disk_name]:
|
||||
diskInfo['ALL']['write_merged_count'] += diskInfo[disk_name]['write_merged_count']
|
||||
|
||||
self.cache[iokey] = {'info':diskio_group,'time':mtime}
|
||||
except Exception as e:
|
||||
# print(mw.getTracebackInfo())
|
||||
pass
|
||||
|
||||
return diskInfo
|
||||
|
||||
def getNetWorkIoData(self, start, end):
|
||||
# 取指定时间段的网络Io
|
||||
data = mw.M('network').dbfile('system').where("addtime>=? AND addtime<=?", (start, end)).field(
|
||||
|
||||
@@ -154,7 +154,7 @@ function mongoReplStatus() {
|
||||
} else{
|
||||
tbody += '<tr><th>状态</th><td>' + rdata.status + '</td><td>主/从</td></tr>\
|
||||
<tr><th>同步文档</th><td>' + rdata.setName + '</td><td>文档名</td></tr>\
|
||||
<tr><th>hosts</th><td><span class="overflow_hide" style="width:260px;" title="'+rdata.hosts+'">' + rdata.hosts + '</span></td><td>服务器所有节点</td></tr>\
|
||||
<tr><th>hosts</th><td><span class="overflow_hide" style="width:300px;word-wrap: break-word;white-space:pre-wrap;" title="'+rdata.hosts+'">' + rdata.hosts + '</span></td><td>服务器所有节点</td></tr>\
|
||||
<tr><th>primary</th><td>' + rdata.primary + '</td><td>主节点</td></tr>\
|
||||
<tr><th>me</th><td>' + rdata.me + '</td><td>本机</td></tr>';
|
||||
}
|
||||
|
||||
+578
-53
@@ -1,35 +1,3 @@
|
||||
$(function() {
|
||||
$(".mem-release").hover(function() {
|
||||
$(this).addClass("shine_green");
|
||||
if (!($(this).hasClass("mem-action"))) {
|
||||
$(this).find(".mem-re-min").hide();
|
||||
$(this).find(".mask").css({ "color": "#d2edd8" });
|
||||
$(this).find(".mem-re-con").css({ "display": "block" });
|
||||
$(this).find(".mem-re-con").animate({ "top": "0", opacity: 1 });
|
||||
$("#memory").text('内存释放');
|
||||
}
|
||||
}, function() {
|
||||
$(this).removeClass("shine_green");
|
||||
$(this).find(".mask").css({ "color": "#20a53a" });
|
||||
$(this).find(".mem-re-con").css({ "top": "15px", opacity: 1, "display": "none" });
|
||||
$("#memory").text(getCookie("mem-before"));
|
||||
$(this).find(".mem-re-min").hide();
|
||||
}).click(function() {
|
||||
$(this).find(".mem-re-min").hide();
|
||||
if (!($(this).hasClass("mem-action"))) {
|
||||
reMemory();
|
||||
var btlen = $(".mem-release").find(".mask span").text();
|
||||
$(this).addClass("mem-action");
|
||||
$(this).find(".mask").css({ "color": "#20a53a" });
|
||||
$(this).find(".mem-re-con").animate({ "top": "-400px", opacity: 0 });
|
||||
$(this).find(".pie_right .right").css({ "transform": "rotate(3deg)" });
|
||||
for (var i = 0; i < btlen; i++) {
|
||||
setTimeout("rocket(" + btlen + "," + i + ")", i * 30);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//获取负载
|
||||
function getLoad(data) {
|
||||
$("#LoadList .mask").html("<span id='Load' style='font-size:14px'>获取中..</span>");
|
||||
@@ -64,7 +32,7 @@ function getLoad(data) {
|
||||
}
|
||||
|
||||
$('#LoadList .circle').click(function() {
|
||||
getNet();
|
||||
// getNet();
|
||||
});
|
||||
|
||||
$('#LoadList .mask').hover(function() {
|
||||
@@ -81,8 +49,7 @@ $('#LoadList .mask').hover(function() {
|
||||
|
||||
|
||||
function showCpuTips(rdata){
|
||||
$('#cpuChart .mask').unbind();
|
||||
$('#cpuChart .mask').hover(function() {
|
||||
$('#cpuChart .mask').unbind().hover(function() {
|
||||
var cpuText = '';
|
||||
if (rdata.cpu[2].length == 1){
|
||||
var cpuUse = parseFloat(rdata.cpu[2][0] == 0 ? 0 : rdata.cpu[2][0]).toFixed(1);
|
||||
@@ -284,6 +251,8 @@ function getNet() {
|
||||
var up, down;
|
||||
$.get("/system/network", function(net) {
|
||||
|
||||
console.log(net);
|
||||
|
||||
$("#InterfaceSpeed").html(lan.index.interfacespeed + ": 1.0Gbps");
|
||||
$("#upSpeed").html(toSize(net.up));
|
||||
$("#downSpeed").html(toSize(net.down));
|
||||
@@ -310,9 +279,9 @@ function getNet() {
|
||||
},'json');
|
||||
}
|
||||
|
||||
//网络Io
|
||||
//网络IO
|
||||
function netImg() {
|
||||
var echartsNetImg = echarts.init(document.getElementById('netImg'));
|
||||
|
||||
var xData = [];
|
||||
var yData = [];
|
||||
var zData = [];
|
||||
@@ -359,7 +328,7 @@ function netImg() {
|
||||
var downNetTmp = toSize(getCookie("downNet"));
|
||||
|
||||
var upNetTmpSize = upNetTmp.split(' ')[0];
|
||||
var downNetTmp = downNetTmp.split(' ')[0]
|
||||
var downNetTmp = downNetTmp.split(' ')[0];
|
||||
|
||||
yData.push(upNetTmpSize);
|
||||
zData.push(downNetTmp);
|
||||
@@ -378,12 +347,12 @@ function netImg() {
|
||||
// 指定图表的配置项和数据
|
||||
var option = {
|
||||
title: {
|
||||
text: lan.index.interface_net,
|
||||
text: "接口流量实时",
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
color: '#888888',
|
||||
fontStyle: 'normal',
|
||||
fontFamily: lan.index.net_font,
|
||||
fontFamily: "宋体",
|
||||
fontSize: 16,
|
||||
}
|
||||
},
|
||||
@@ -474,6 +443,8 @@ function netImg() {
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
var echartsNetImg = echarts.init(document.getElementById('netImg'));
|
||||
setInterval(function() {
|
||||
getNet();
|
||||
addData(true);
|
||||
@@ -516,8 +487,7 @@ function setImg() {
|
||||
};
|
||||
});
|
||||
|
||||
$('.diskbox .mask').unbind();
|
||||
$('.diskbox .mask').hover(function() {
|
||||
$('.diskbox .mask').unbind().hover(function() {
|
||||
layer.closeAll('tips');
|
||||
var that = this;
|
||||
var conterError = $(this).attr("data");
|
||||
@@ -638,7 +608,10 @@ function reBoot() {
|
||||
area: '330px',
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="rebt-con"><div class="rebt-li"><a data-id="server" href="javascript:;">重启服务器</a></div><div class="rebt-li"><a data-id="panel" href="javascript:;">重启面板</a></div></div>'
|
||||
content: '<div class="rebt-con">\
|
||||
<div class="rebt-li"><a data-id="server" href="javascript:;">重启服务器</a></div>\
|
||||
<div class="rebt-li"><a data-id="panel" href="javascript:;">重启面板</a></div>\
|
||||
</div>'
|
||||
});
|
||||
|
||||
$('.rebt-con a').click(function () {
|
||||
@@ -779,17 +752,18 @@ function showDanger(num, port) {
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
content: '<div class="pd20">\
|
||||
<table class="f14 showDanger"><tbody>\
|
||||
<tr><td class="text-right" width="150">风险类型:</td><td class="f16" style="color:red">暴力破解 <a href="https://www.bt.cn/bbs/thread-9562-1-1.html" class="btlink f14" style="margin-left:10px" target="_blank">说明</a></td></tr>\
|
||||
<tr><td class="text-right">累计遭遇攻击总数:</td><td class="f16" style="color:red">' + num + ' <a href="javascript:showDangerIP();" class="btlink f14" style="margin-left:10px">详细</a><span class="c9 f12" style="margin-left:10px">(数据直接来源本服务器日志)</span></td></tr>\
|
||||
<tr><td class="text-right">风险等级:</td><td class="f16" style="color:red">较高风险</td></tr>\
|
||||
<tr><td class="text-right" style="vertical-align:top">风险描述:</td><td style="line-height:20px">' + atxt + '</td></tr>\
|
||||
<tr><td class="text-right" style="vertical-align:top">可参考解决方案:</td><td><p style="margin-bottom:8px">方案一:修改SSH默认端口,修改SSH验证方式为数字证书,清除近期登陆日志。</p><p>方案二:购买宝塔企业运维版,一键部署安全隔离服务,高效且方便。</p></td></tr>\
|
||||
</tbody></table>\
|
||||
<div class="mtb20 text-center"><a href="https://www.bt.cn/admin/index.html" target="_blank" class="btn btn-success">立即部署隔离防护</a></div>\
|
||||
</div>'
|
||||
<table class="f14 showDanger">\
|
||||
<tbody>\
|
||||
<tr><td class="text-right" width="150">风险类型:</td><td class="f16" style="color:red">暴力破解 <a href="https://www.bt.cn/bbs/thread-9562-1-1.html" class="btlink f14" style="margin-left:10px" target="_blank">说明</a></td></tr>\
|
||||
<tr><td class="text-right">累计遭遇攻击总数:</td><td class="f16" style="color:red">' + num + ' <a href="javascript:showDangerIP();" class="btlink f14" style="margin-left:10px">详细</a><span class="c9 f12" style="margin-left:10px">(数据直接来源本服务器日志)</span></td></tr>\
|
||||
<tr><td class="text-right">风险等级:</td><td class="f16" style="color:red">较高风险</td></tr>\
|
||||
<tr><td class="text-right" style="vertical-align:top">风险描述:</td><td style="line-height:20px">' + atxt + '</td></tr>\
|
||||
<tr><td class="text-right" style="vertical-align:top">可参考解决方案:</td><td><p style="margin-bottom:8px">方案一:修改SSH默认端口,修改SSH验证方式为数字证书,清除近期登陆日志。</p><p>方案二:购买宝塔企业运维版,一键部署安全隔离服务,高效且方便。</p></td></tr>\
|
||||
</tbody>\
|
||||
</table>\
|
||||
</div>'
|
||||
});
|
||||
$(".showDanger td").css("padding", "8px")
|
||||
$(".showDanger td").css("padding", "8px");
|
||||
}
|
||||
|
||||
function pluginInit(){
|
||||
@@ -913,3 +887,554 @@ function loadKeyDataCount(){
|
||||
call(pname);
|
||||
}
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$(".mem-release").hover(function() {
|
||||
$(this).addClass("shine_green");
|
||||
if (!($(this).hasClass("mem-action"))) {
|
||||
$(this).find(".mem-re-min").hide();
|
||||
$(this).find(".mask").css({ "color": "#d2edd8" });
|
||||
$(this).find(".mem-re-con").css({ "display": "block" });
|
||||
$(this).find(".mem-re-con").animate({ "top": "0", opacity: 1 });
|
||||
$("#memory").text('内存释放');
|
||||
}
|
||||
}, function() {
|
||||
$(this).removeClass("shine_green");
|
||||
$(this).find(".mask").css({ "color": "#20a53a" });
|
||||
$(this).find(".mem-re-con").css({ "top": "15px", opacity: 1, "display": "none" });
|
||||
$("#memory").text(getCookie("mem-before"));
|
||||
$(this).find(".mem-re-min").hide();
|
||||
}).click(function() {
|
||||
$(this).find(".mem-re-min").hide();
|
||||
if (!($(this).hasClass("mem-action"))) {
|
||||
reMemory();
|
||||
var btlen = $(".mem-release").find(".mask span").text();
|
||||
$(this).addClass("mem-action");
|
||||
$(this).find(".mask").css({ "color": "#20a53a" });
|
||||
$(this).find(".mem-re-con").animate({ "top": "-400px", opacity: 0 });
|
||||
$(this).find(".pie_right .right").css({ "transform": "rotate(3deg)" });
|
||||
for (var i = 0; i < btlen; i++) {
|
||||
setTimeout("rocket(" + btlen + "," + i + ")", i * 30);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("select[name='network-io'],select[name='disk-io']").change(function () {
|
||||
var key = $(this).val(), type = $(this).attr('name');
|
||||
if (type == 'network-io') {
|
||||
if (key == 'ALL') {
|
||||
key = '';
|
||||
}
|
||||
setCookie('network_io_key', key);
|
||||
} else {
|
||||
if (key == 'ALL') {
|
||||
key = '';
|
||||
}
|
||||
setCookie('disk_io_key', key);
|
||||
}
|
||||
});
|
||||
|
||||
$('.tabs-nav span').click(function () {
|
||||
var indexs = $(this).index();
|
||||
$(this).addClass('active').siblings().removeClass('active');
|
||||
$('.tabs-content .tabs-item:eq(' + indexs + ')').addClass('tabs-active').siblings().removeClass('tabs-active');
|
||||
$('.tabs-down select:eq(' + indexs + ')').removeClass('hide').siblings().addClass('hide');
|
||||
switch (indexs) {
|
||||
case 0:
|
||||
index.net.table.resize();
|
||||
break;
|
||||
case 1:
|
||||
index.iostat.table.resize();
|
||||
break;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
var index = {
|
||||
common:{
|
||||
ts:function (m) { return m < 10 ? '0' + m : m },
|
||||
format:function (sjc) {
|
||||
var time = new Date(sjc);
|
||||
var h = time.getHours();
|
||||
var mm = time.getMinutes();
|
||||
var s = time.getSeconds();
|
||||
return h+ ':' + mm + ':' +s;
|
||||
},
|
||||
getTime:function () {
|
||||
var now = new Date();
|
||||
var hour = now.getHours();
|
||||
var minute = now.getMinutes();
|
||||
var second = now.getSeconds();
|
||||
if (minute < 10) {
|
||||
minute = "0" + minute;
|
||||
}
|
||||
if (second < 10) {
|
||||
second = "0" + second;
|
||||
}
|
||||
var nowdate = hour + ":" + minute + ":" + second;
|
||||
return nowdate;
|
||||
},
|
||||
},
|
||||
net: {
|
||||
table: null,
|
||||
data: {
|
||||
xData: [],
|
||||
yData: [],
|
||||
zData: []
|
||||
},
|
||||
default_unit : 'KB/s',
|
||||
init_select : false,
|
||||
init: function(){
|
||||
for (var i = 8; i >= 0; i--) {
|
||||
var time = (new Date()).getTime();
|
||||
index.net.data.xData.push(index.common.format(time - (i * 3 * 1000)));
|
||||
index.net.data.yData.push(0);
|
||||
index.net.data.zData.push(0);
|
||||
}
|
||||
|
||||
index.net.table = echarts.init(document.getElementById('netImg'));
|
||||
var option = index.net.defaultOption();
|
||||
index.net.table.setOption(option);
|
||||
|
||||
window.addEventListener("resize", function () {
|
||||
index.net.table.resize();
|
||||
});
|
||||
},
|
||||
render:function(){
|
||||
index.net.table.setOption({
|
||||
yAxis: {
|
||||
name: '单位 '+ index.net.default_unit,
|
||||
splitLine: { lineStyle: { color: "#eee" } },
|
||||
axisLine: { lineStyle: { color: "#666" } }
|
||||
},
|
||||
xAxis: {
|
||||
data: index.net.data.xData
|
||||
},
|
||||
series: [{
|
||||
name: lan.index.net_up,
|
||||
data: index.net.data.yData
|
||||
}, {
|
||||
name: lan.index.net_down,
|
||||
data: index.net.data.zData
|
||||
}]
|
||||
});
|
||||
},
|
||||
defaultOption:function(){
|
||||
var option = {
|
||||
title: {
|
||||
text: "",
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
color: '#888888',
|
||||
fontStyle: 'normal',
|
||||
fontFamily: "宋体",
|
||||
fontSize: 16,
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: [lan.index.net_up, lan.index.net_down],
|
||||
bottom: '2%'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: index.net.data.xData,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#666"
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位 '+ index.net.default_unit,
|
||||
splitLine: {
|
||||
lineStyle: { color: "#eee" }
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: { color: "#666" }
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: '上行',
|
||||
type: 'line',
|
||||
data: index.net.data.yData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(255, 140, 0,0.5)'
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(255, 140, 0,0.8)'
|
||||
}], false)
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#f7b851'
|
||||
}
|
||||
},
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '下行',
|
||||
type: 'line',
|
||||
data: index.net.data.zData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(30, 144, 255,0.5)',
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(30, 144, 255,0.8)',
|
||||
}], false)
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#52a9ff',
|
||||
}
|
||||
},
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1,
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
return option;
|
||||
},
|
||||
|
||||
|
||||
add: function (up, down) {
|
||||
var _net = this;
|
||||
var limit = 8;
|
||||
var d = new Date()
|
||||
if (_net.data.xData.length >= limit) _net.data.xData.splice(0, 1);
|
||||
if (_net.data.yData.length >= limit) _net.data.yData.splice(0, 1);
|
||||
if (_net.data.zData.length >= limit) _net.data.zData.splice(0, 1);
|
||||
|
||||
|
||||
var upTmpSize = toSize(up).split(' ')[0];
|
||||
var downTmpSize = toSize(down).split(' ')[0];
|
||||
|
||||
var tmp = up;
|
||||
if (down>up){
|
||||
tmp = down;
|
||||
}
|
||||
index.net.default_unit = toSize(tmp).split(' ')[1] + '/s';
|
||||
|
||||
_net.data.zData.push(downTmpSize);
|
||||
_net.data.yData.push(upTmpSize);
|
||||
_net.data.xData.push(d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds());
|
||||
},
|
||||
renderSelect:function(net){
|
||||
// console.log(net);
|
||||
if (!index.net.init_select){
|
||||
var option = '';
|
||||
var network = net.network;
|
||||
var network_io_key = getCookie('network_io_key');
|
||||
|
||||
for (var name in network) {
|
||||
if (name == 'ALL'){
|
||||
option += '<option value="'+name+'">全部</option>';
|
||||
} else if (network_io_key == name){
|
||||
option += '<option value="'+name+'" selected>'+name+'</option>';
|
||||
} else {
|
||||
option += '<option value="'+name+'">'+name+'</option>';
|
||||
}
|
||||
}
|
||||
$('select[name="network-io"]').html(option);
|
||||
index.net.init_select = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
iostat:{
|
||||
table: null,
|
||||
data: {
|
||||
xData: [],
|
||||
yData: [],
|
||||
zData: [],
|
||||
tipsData: []
|
||||
},
|
||||
init_select:false,
|
||||
default_unit : 'MB/s',
|
||||
init:function(){
|
||||
for (var i = 8; i >= 0; i--) {
|
||||
var time = (new Date()).getTime();
|
||||
index.iostat.data.xData.push(index.common.format(time - (i * 3 * 1000)));
|
||||
index.iostat.data.yData.push(0);
|
||||
index.iostat.data.zData.push(0);
|
||||
index.iostat.data.tipsData.push({});
|
||||
}
|
||||
|
||||
index.iostat.table = echarts.init(document.getElementById('ioStat'));
|
||||
var option = index.iostat.defaultOption();
|
||||
index.iostat.table.setOption(option);
|
||||
|
||||
window.addEventListener("resize", function () {
|
||||
index.iostat.table.resize();
|
||||
});
|
||||
},
|
||||
|
||||
render:function(){
|
||||
index.iostat.table.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter :function (config) {
|
||||
var _config = config, _tips = "时间:" + _config[0].axisValue + "<br />", options = {
|
||||
read_bytes: '读取字节数',
|
||||
read_count: '读取次数 ',
|
||||
read_merged_count: '合并读取次数',
|
||||
read_time: '读取延迟',
|
||||
write_bytes: '写入字节数',
|
||||
write_count: '写入次数',
|
||||
write_merged_count: '合并写入次数',
|
||||
write_time: '写入延迟',
|
||||
}, data = index.iostat.data.tipsData[config[0].dataIndex], list = ['read_count', 'write_count', 'read_merged_count', 'write_merged_count', 'read_time', 'write_time',];
|
||||
for (var i = 0; i < config.length; i++) {
|
||||
if (typeof config[i].data == "undefined") {
|
||||
return false;
|
||||
}
|
||||
_tips += '<span style="display: inline-block;width: 10px;height: 10px;border-radius: 50%;background: ' + config[i].color + ';"></span> <span>' + config[i].seriesName + ':' + config[i].data + ' MB/s' + '</span><br />'
|
||||
}
|
||||
$.each(list, function (index, item) {
|
||||
|
||||
if (typeof data[item] != 'undefined'){
|
||||
_tips += '<span style="display: inline-block;width: 10px;height: 10px;"></span> <span style="' + (item.indexOf('time') > -1 ? ('color:' + ((data[item] > 100 && data[item] < 1000) ? '#ff9900' : (data[item] >= 1000 ? 'red' : '#20a53a'))) : '') + '">' + options[item] + ':' + data[item] + (item.indexOf('time') > -1 ? ' ms' : ' 次/秒') + '</span><br />';
|
||||
}
|
||||
})
|
||||
return _tips;
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位 '+ index.iostat.default_unit,
|
||||
splitLine: { lineStyle: { color: "#eee" } },
|
||||
axisLine: { lineStyle: { color: "#666" } }
|
||||
},
|
||||
xAxis: {
|
||||
data: index.iostat.data.xData
|
||||
},
|
||||
series: [{
|
||||
name: "读取",
|
||||
data: index.iostat.data.yData
|
||||
}, {
|
||||
name: "写入",
|
||||
data: index.iostat.data.zData
|
||||
}]
|
||||
});
|
||||
},
|
||||
defaultOption:function(){
|
||||
var option = {
|
||||
title: {
|
||||
text: "",
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
color: '#888888',
|
||||
fontStyle: 'normal',
|
||||
fontFamily: "宋体",
|
||||
fontSize: 16,
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ["读取", "写入"],
|
||||
bottom: '2%'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: index.iostat.data.xData,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#666"
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位 '+ index.iostat.default_unit,
|
||||
splitLine: {
|
||||
lineStyle: { color: "#eee" }
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: { color: "#666" }
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: '读取',
|
||||
type: 'line',
|
||||
data: index.iostat.data.yData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
symbol: 'circle',
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: 'rgb(255, 70, 131)'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgb(255, 70, 131)'
|
||||
}
|
||||
},
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1,
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '写入',
|
||||
type: 'line',
|
||||
data: index.iostat.data.zData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: 'rgba(46, 165, 186, .7)'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgba(46, 165, 186, .7)'
|
||||
}
|
||||
},
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1,
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
return option;
|
||||
},
|
||||
|
||||
renderSelect:function(data){
|
||||
if (!index.iostat.init_select){
|
||||
var option = '';
|
||||
var iostat = data.iostat;
|
||||
var disk_io_key = getCookie('disk_io_key');
|
||||
|
||||
for (var name in iostat) {
|
||||
if (name == 'ALL'){
|
||||
option += '<option value="'+name+'">全部</option>';
|
||||
} else if (disk_io_key == name){
|
||||
option += '<option value="'+name+'" selected>'+name+'</option>';
|
||||
} else {
|
||||
option += '<option value="'+name+'">'+name+'</option>';
|
||||
}
|
||||
}
|
||||
$('select[name="disk-io"]').html(option);
|
||||
index.iostat.init_select = true;
|
||||
}
|
||||
},
|
||||
add: function (read, write, data) {
|
||||
var _iostat = this;
|
||||
var limit = 8;
|
||||
var d = new Date()
|
||||
if (_iostat.data.xData.length >= limit) _iostat.data.xData.splice(0, 1);
|
||||
if (_iostat.data.yData.length >= limit) _iostat.data.yData.splice(0, 1);
|
||||
if (_iostat.data.zData.length >= limit) _iostat.data.zData.splice(0, 1);
|
||||
if (_iostat.data.tipsData.length >= limit) _iostat.data.tipsData.splice(0, 1);
|
||||
|
||||
|
||||
var readTmpSize = toSizeMB(read).split(' ')[0];
|
||||
var writeTmpSize = toSizeMB(write).split(' ')[0];
|
||||
|
||||
_iostat.data.zData.push(writeTmpSize);
|
||||
_iostat.data.yData.push(readTmpSize);
|
||||
_iostat.data.tipsData.push(data);
|
||||
_iostat.data.xData.push(d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds());
|
||||
},
|
||||
|
||||
},
|
||||
getData:function(){
|
||||
|
||||
$.get("/system/network", function(net) {
|
||||
|
||||
//网络IO
|
||||
var network_io_key = getCookie('network_io_key');
|
||||
var network_data = net.network;
|
||||
var network_select = network_data['ALL'];
|
||||
if (network_io_key && network_io_key != ''){
|
||||
network_select = network_data[network_io_key];
|
||||
}
|
||||
|
||||
index.net.add(network_select.up,network_select.down);
|
||||
index.net.render();
|
||||
index.net.renderSelect(net);
|
||||
|
||||
$("#upSpeed").html(toSize(network_select.up));
|
||||
$("#downSpeed").html(toSize(network_select.down));
|
||||
|
||||
$("#downAll").html(toSize(network_select.downTotal));
|
||||
$("#downAll").attr('title','数据包:' + network_select.downPackets)
|
||||
$("#upAll").html(toSize(network_select.upTotal));
|
||||
$("#upAll").attr('title','数据包:' + network_select.upPackets)
|
||||
|
||||
|
||||
//磁盘IO
|
||||
var disk_io_key = getCookie('disk_io_key');
|
||||
var iostat_data = net.iostat;
|
||||
var iostat_select = iostat_data['ALL'];
|
||||
if (disk_io_key && disk_io_key != ''){
|
||||
iostat_select = iostat_data[disk_io_key];
|
||||
}
|
||||
|
||||
index.iostat.add(iostat_select.read_bytes,iostat_select.write_bytes, iostat_select);
|
||||
index.iostat.render();
|
||||
index.iostat.renderSelect(net);
|
||||
|
||||
$("#readBytes").html(toSize(iostat_select.read_bytes));
|
||||
$("#writeBytes").html(toSize(iostat_select.write_bytes));
|
||||
$("#diskIops").html(iostat_select.read_count);
|
||||
$("#diskTime").html(iostat_select.write_time);
|
||||
|
||||
|
||||
$("#core").html(net.cpu[1] + " " + lan.index.cpu_core);
|
||||
$("#state").html(net.cpu[0]);
|
||||
|
||||
setcolor(net.cpu[0], "#state", 30, 70, 90);
|
||||
//负载
|
||||
getLoad(net.load);
|
||||
//内存
|
||||
setMemImg(net.mem);
|
||||
//绑定hover事件
|
||||
setImg();
|
||||
showCpuTips(net);
|
||||
|
||||
},'json');
|
||||
},
|
||||
task:function(){
|
||||
index.getData();
|
||||
setInterval(function() {
|
||||
index.getData();
|
||||
}, 3000);
|
||||
},
|
||||
init: function(){
|
||||
index.net.init();
|
||||
index.iostat.init();
|
||||
index.task();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,17 @@ function toSize(a) {
|
||||
}
|
||||
}
|
||||
|
||||
function toSizeMB(a) {
|
||||
var d = [" KB", " MB"];
|
||||
var e = 1024;
|
||||
var i = 0;
|
||||
for(var b = 0; b < d.length; b++) {
|
||||
a /= e;
|
||||
i = b;
|
||||
}
|
||||
return a.toFixed(2) + d[i]
|
||||
}
|
||||
|
||||
function toTrim(x) {
|
||||
return x.replace(/^\s+|\s+$/gm,'');
|
||||
}
|
||||
|
||||
@@ -5096,4 +5096,110 @@ select[disabled]{
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
|
||||
.title.tabs-nav {
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.title.tabs-nav span {
|
||||
display: inline-block;
|
||||
height: 50px;
|
||||
min-width: 100px;
|
||||
padding: 0 20px;
|
||||
line-height: 50px;
|
||||
font-size: 15px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title.tabs-nav span.active {
|
||||
color: #20a53a;
|
||||
background: #20a53a08;
|
||||
}
|
||||
|
||||
|
||||
.title.tabs-nav select {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 50%;
|
||||
margin-top: -12px;
|
||||
}
|
||||
|
||||
select[name="network-io"], select[name="disk-io"] {
|
||||
font-size: 13px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
padding: 2px;
|
||||
border-radius: 0;
|
||||
border-color: #ececec;
|
||||
}
|
||||
|
||||
.tabs-content .tabs-item {
|
||||
display: none;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.tabs-content .tabs-active.tabs-item {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bw-info {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.bw-info>div {
|
||||
float: left;
|
||||
padding-top: 35px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bw-info>div p {
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.bw-info>div a {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.bw-info .ico-down,
|
||||
.bw-info .ico-up,
|
||||
.bw-info .ico-write,
|
||||
.bw-info .ico-read {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
display: inline-block;
|
||||
margin-right: 3px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.bw-info .ico-down {
|
||||
background-color: #52a9ff;
|
||||
}
|
||||
|
||||
.bw-info .ico-up {
|
||||
background-color: #f7b851;
|
||||
}
|
||||
|
||||
.bw-info .ico-write {
|
||||
background-color: #6CC0CF;
|
||||
}
|
||||
|
||||
.bw-info .ico-read {
|
||||
background-color: #FF4683;
|
||||
}
|
||||
|
||||
.bw-info ul li {
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
}
|
||||
|
||||
.bw-info ul li.bi-line {
|
||||
border-bottom: #ddd solid 1px;
|
||||
}
|
||||
@@ -99,15 +99,45 @@
|
||||
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 pull-left pd0">
|
||||
<div class="pl7">
|
||||
<div class="bgw" style="height:491px">
|
||||
<div class="title c6 f16 plr15">流量</div>
|
||||
<div class="bw-info">
|
||||
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-up"></span>上行</p><a id="upSpeed">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-down"></span>下行</p><a id="downSpeed">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9">总发送</p><a id="upAll">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9">总接收</p><a id="downAll">0</a></div>
|
||||
<div class="bgw radius4" style="height:491px">
|
||||
<div class="title c6 f16 plr15 tabs-nav">
|
||||
<div class="tab-list">
|
||||
<span class="tabs-item active">流量</span>
|
||||
<span class="tabs-item">磁盘IO</span>
|
||||
</div>
|
||||
|
||||
<div class="tabs-down">
|
||||
<select class="bt-input-text" name="network-io" style="font-size: 12px;">
|
||||
<option value="ALL">全部</option>
|
||||
</select>
|
||||
<select class="bt-input-text hide" name="disk-io" style="font-size: 12px;">
|
||||
<option value="ALL">全部</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="netImg" style="width:100%;height:330px;"></div>
|
||||
|
||||
<div class="tabs-content">
|
||||
<div class="tabs-active radius4 tabs-item">
|
||||
<div class="bw-info">
|
||||
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-up"></span>上行</p><a id="upSpeed">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-down"></span>下行</p><a id="downSpeed">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9">总发送</p><a id="upAll">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9">总接收</p><a id="downAll">0</a></div>
|
||||
</div>
|
||||
<div id="netImg" style="width:100%;height:330px;"></div>
|
||||
</div>
|
||||
|
||||
<div class="radius4 tabs-item">
|
||||
<div class="bw-info">
|
||||
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-read"></span>读取</p><a id="readBytes">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-write"></span>写入</p><a id="writeBytes">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9">每秒读写</p><a id="diskIops">0</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9">IO延迟</p><a id="diskTime" style="color: rgb(32, 165, 58);">0</a></div>
|
||||
</div>
|
||||
<div id="ioStat" style="width:100%;height:330px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -119,8 +149,8 @@
|
||||
<script type="text/javascript" src="/static/app/index.js?v={{config.version}}"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
netImg();
|
||||
setImg();
|
||||
index.init();
|
||||
|
||||
pluginInit();
|
||||
//加载关键数据总数
|
||||
loadKeyDataCount();
|
||||
|
||||
Reference in New Issue
Block a user