mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 19:59:26 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6a3cf7882 | ||
|
|
a1afe5e846 | ||
|
|
594e8c4b2b | ||
|
|
cc015bad61 | ||
|
|
bc9461dea6 | ||
|
|
0a25598c15 | ||
|
|
7a9a8a08b6 | ||
|
|
8eb728defa | ||
|
|
7f8ffbf178 | ||
|
|
cb0027e903 | ||
|
|
e0ebdd922d | ||
|
|
d6f43a86c9 | ||
|
|
dfe7becdb1 | ||
|
|
57f4162cb8 | ||
|
|
a9ce4f2e23 | ||
|
|
b501d62d91 | ||
|
|
45ffba1559 | ||
|
|
28d0fbe106 | ||
|
|
eeb8fee3b3 | ||
|
|
0e1fbdcfb9 | ||
|
|
df2744816b | ||
|
|
862c09778a | ||
|
|
8f9a1888ff | ||
|
|
66351dc3a7 | ||
|
|
55c4709c93 | ||
|
|
e27ae42270 | ||
|
|
70805de98e | ||
|
|
c0e09e43a2 | ||
|
|
b69a32c81f | ||
|
|
2431833cce | ||
|
|
a85d8ec429 | ||
|
|
ce5a6edeea | ||
|
|
aa195dea2c | ||
|
|
840a3c5911 | ||
|
|
ca87ab78b3 | ||
|
|
d9fc411168 | ||
|
|
e468ab16eb | ||
|
|
c545062d07 | ||
|
|
e620fd67e3 | ||
|
|
aa9a412e9a |
@@ -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(
|
||||
|
||||
@@ -17,7 +17,7 @@ pluginService('clean');
|
||||
|
||||
function pRead(){
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>启动后,加入到计划中[2:30]执行。</li>';
|
||||
readme += '<li>启动后,加入到计划任务每隔7天[0:15]执行。</li>';
|
||||
readme += '<li>【*】代表要删除。</li>';
|
||||
readme += '<li>添加/删除清除日志,可在`配置修改`中添加/删除。</li>';
|
||||
readme += '<li>如果是目录,会寻找【.log】后缀的文件清空。</li>';
|
||||
|
||||
+20
-1
@@ -99,7 +99,26 @@ def initConf():
|
||||
"/var/log/secure",
|
||||
"/var/log/lastlog",
|
||||
"/var/log/cron",
|
||||
"/www/server/cron"
|
||||
"/www/server/rsyncd",
|
||||
"/www/server/sphinx/index",
|
||||
"/www/server/mongodb/logs",
|
||||
"/www/server/php/53/var/log",
|
||||
"/www/server/php/54/var/log",
|
||||
"/www/server/php/55/var/log",
|
||||
"/www/server/php/56/var/log",
|
||||
"/www/server/php/70/var/log",
|
||||
"/www/server/php/71/var/log",
|
||||
"/www/server/php/72/var/log",
|
||||
"/www/server/php/73/var/log",
|
||||
"/www/server/php/74/var/log",
|
||||
"/www/server/php/80/var/log",
|
||||
"/www/server/php/81/var/log",
|
||||
"/www/server/php/82/var/log",
|
||||
"/www/server/php/83/var/log",
|
||||
"/www/server/php/84/var/log",
|
||||
"/www/server/phpmyadmin",
|
||||
"/www/server/redis/data",
|
||||
"/www/server/cron",
|
||||
]
|
||||
for i in clogcom:
|
||||
if os.path.exists(i):
|
||||
|
||||
+30
-57
@@ -37,57 +37,36 @@ def getConfigData():
|
||||
return json.loads(mw.readFile(getTaskConf()))
|
||||
except:
|
||||
pass
|
||||
return []
|
||||
|
||||
|
||||
def getConfigTpl():
|
||||
tpl = {
|
||||
"name": "",
|
||||
return {
|
||||
"task_id": -1,
|
||||
"period": "day-n",
|
||||
"where1": "7",
|
||||
"hour": "0",
|
||||
"minute": "15",
|
||||
}
|
||||
return tpl
|
||||
|
||||
|
||||
def createBgTask():
|
||||
removeBgTask()
|
||||
args = {
|
||||
"period": "day",
|
||||
"hour": "0",
|
||||
"minute": "15",
|
||||
}
|
||||
createBgTaskByName(getPluginName(), args)
|
||||
createBgTaskByName(getPluginName())
|
||||
|
||||
|
||||
def createBgTaskByName(name, args):
|
||||
cfg = getConfigTpl()
|
||||
def createBgTaskByName(name):
|
||||
args = getConfigData()
|
||||
_name = "[勿删]日志清理[" + name + "]"
|
||||
res = mw.M("crontab").field("id, name").where("name=?", (_name,)).find()
|
||||
if res:
|
||||
return True
|
||||
|
||||
if "task_id" in cfg.keys() and cfg["task_id"] > 0:
|
||||
if "task_id" in args and args["task_id"] > 0:
|
||||
res = mw.M("crontab").field("id, name").where(
|
||||
"id=?", (cfg["task_id"],)).find()
|
||||
if res and res["id"] == cfg["task_id"]:
|
||||
"id=?", (args["task_id"],)).find()
|
||||
if res and res["id"] == args["task_id"]:
|
||||
print("计划任务已经存在!")
|
||||
return True
|
||||
import crontab_api
|
||||
api = crontab_api.crontab_api()
|
||||
|
||||
period = args['period']
|
||||
_hour = ''
|
||||
_minute = ''
|
||||
_where1 = ''
|
||||
_type_day = "day"
|
||||
if period == 'day':
|
||||
_type_day = 'day'
|
||||
_hour = args['hour']
|
||||
_minute = args['minute']
|
||||
elif period == 'minute-n':
|
||||
_type_day = 'minute-n'
|
||||
_where1 = args['minute-n']
|
||||
_minute = ''
|
||||
|
||||
mw_dir = mw.getRunDir()
|
||||
cmd = '''
|
||||
mw_dir=%s
|
||||
@@ -105,11 +84,11 @@ logs_file=$plugin_path/${rname}.log
|
||||
|
||||
params = {
|
||||
'name': _name,
|
||||
'type': _type_day,
|
||||
'type': args['period'],
|
||||
'week': "",
|
||||
'where1': _where1,
|
||||
'hour': _hour,
|
||||
'minute': _minute,
|
||||
'where1': args['where1'],
|
||||
'hour': args['hour'],
|
||||
'minute': args['minute'],
|
||||
'save': "",
|
||||
'backup_to': "",
|
||||
'stype': "toShell",
|
||||
@@ -120,30 +99,24 @@ logs_file=$plugin_path/${rname}.log
|
||||
|
||||
task_id = api.add(params)
|
||||
if task_id > 0:
|
||||
cfg["task_id"] = task_id
|
||||
cfg["name"] = name
|
||||
|
||||
_dd = getConfigData()
|
||||
_dd.append(cfg)
|
||||
mw.writeFile(getTaskConf(), json.dumps(_dd))
|
||||
args["task_id"] = task_id
|
||||
args["name"] = name
|
||||
mw.writeFile(getTaskConf(), json.dumps(args))
|
||||
|
||||
|
||||
def removeBgTask():
|
||||
cfg_list = getConfigData()
|
||||
for x in range(len(cfg_list)):
|
||||
cfg = cfg_list[x]
|
||||
if "task_id" in cfg.keys() and cfg["task_id"] > 0:
|
||||
res = mw.M("crontab").field("id, name").where(
|
||||
"id=?", (cfg["task_id"],)).find()
|
||||
if res and res["id"] == cfg["task_id"]:
|
||||
import crontab_api
|
||||
api = crontab_api.crontab_api()
|
||||
data = api.delete(cfg["task_id"])
|
||||
if data[0]:
|
||||
cfg["task_id"] = -1
|
||||
cfg_list[x] = cfg
|
||||
mw.writeFile(getTaskConf(), '[]')
|
||||
return True
|
||||
cfg = getConfigData()
|
||||
if "task_id" in cfg and cfg["task_id"] > 0:
|
||||
res = mw.M("crontab").field("id, name").where(
|
||||
"id=?", (cfg["task_id"],)).find()
|
||||
if res and res["id"] == cfg["task_id"]:
|
||||
import crontab_api
|
||||
api = crontab_api.crontab_api()
|
||||
data = api.delete(cfg["task_id"])
|
||||
if data[0]:
|
||||
cfg["task_id"] = -1
|
||||
mw.writeFile(getTaskConf(), json.loads(cfg))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
@@ -496,7 +496,7 @@ def runReplInfo():
|
||||
|
||||
d = getConfigData()
|
||||
result = {}
|
||||
if 'replSetName' in d['replication']:
|
||||
if 'replication' in d and 'replSetName' in d['replication']:
|
||||
result['repl_name'] = d['replication']['replSetName']
|
||||
|
||||
result['status'] = '无'
|
||||
@@ -1505,6 +1505,14 @@ def installPreInspection(version):
|
||||
return '暂时仅支持{}'.format(','.join(supportOs))
|
||||
return 'ok'
|
||||
|
||||
def uninstallPreInspection(version):
|
||||
stop()
|
||||
|
||||
import plugins_api
|
||||
plugins_api.plugins_api().removeIndex(getPluginName(), version)
|
||||
|
||||
return "请手动删除MongoDB[{}]<br/> rm -rf {}".format(version, getServerDir())
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
|
||||
@@ -1524,6 +1532,8 @@ if __name__ == "__main__":
|
||||
print(reload())
|
||||
elif func == 'install_pre_inspection':
|
||||
print(installPreInspection(version))
|
||||
elif func == 'uninstall_pre_inspection':
|
||||
print(uninstallPreInspection(version))
|
||||
elif func == 'initd_status':
|
||||
print(initdStatus())
|
||||
elif func == 'initd_install':
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"title": "MongoDB",
|
||||
"shell": "install.sh",
|
||||
"install_pre_inspection":true,
|
||||
"uninstall_pre_inspection":true,
|
||||
"versions":["4.4","5.0","6.0","7.0"],
|
||||
"tip": "soft",
|
||||
"checks": "server/mongodb",
|
||||
|
||||
@@ -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>';
|
||||
}
|
||||
|
||||
@@ -1070,6 +1070,81 @@ def importDbExternal():
|
||||
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
def importDbExternalProgress():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
file = args['file']
|
||||
name = args['name']
|
||||
|
||||
cmd = 'cd '+mw.getServerDir()+'/mdserver-web && source bin/activate && '
|
||||
cmd += 'python3 '+mw.getServerDir()+'/mdserver-web/plugins/mysql/index.py import_db_external_progress_bar {"file":"'+file+'","name":"'+name+'"}'
|
||||
return mw.returnJson(True, 'ok',cmd)
|
||||
|
||||
def importDbExternalProgressBar():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
file = args['file']
|
||||
name = args['name']
|
||||
|
||||
import_dir = mw.getRootDir() + '/backup/import/'
|
||||
|
||||
file_path = import_dir + file
|
||||
if not os.path.exists(file_path):
|
||||
return mw.returnJson(False, '文件突然消失?')
|
||||
|
||||
exts = ['sql', 'gz', 'zip']
|
||||
ext = mw.getFileSuffix(file)
|
||||
if ext not in exts:
|
||||
return mw.returnJson(False, '导入数据库格式不对!')
|
||||
|
||||
tmp = file.split('/')
|
||||
tmpFile = tmp[len(tmp) - 1]
|
||||
tmpFile = tmpFile.replace('.sql.' + ext, '.sql')
|
||||
tmpFile = tmpFile.replace('.' + ext, '.sql')
|
||||
tmpFile = tmpFile.replace('tar.', '')
|
||||
|
||||
# print(tmpFile)
|
||||
import_sql = ""
|
||||
if file.find("sql.gz") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && gzip -dc ' + \
|
||||
file + " > " + import_dir + tmpFile
|
||||
info = mw.execShell(cmd)
|
||||
if info[1] == "":
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find(".zip") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && unzip -o ' + file
|
||||
mw.execShell(cmd)
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find("tar.gz") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && tar -zxvf ' + file
|
||||
mw.execShell(cmd)
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find(".sql") > -1 and file.find(".sql.gz") == -1:
|
||||
import_sql = import_dir + file
|
||||
|
||||
if import_sql == "":
|
||||
return mw.returnJson(False, '未找SQL文件')
|
||||
|
||||
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
|
||||
sock = getSocketFile()
|
||||
|
||||
my_cnf = getConf()
|
||||
mysql_cmd = getServerDir() + '/bin/mysql --defaults-file=' + my_cnf + \
|
||||
' -uroot -p"' + pwd + '" -f ' + name
|
||||
mysql_cmd_progress_bar = "pv -t -p " + import_sql + '|'+ mysql_cmd
|
||||
print(mysql_cmd_progress_bar)
|
||||
rdata = os.system(mysql_cmd_progress_bar)
|
||||
return ""
|
||||
|
||||
|
||||
def importDbBackup():
|
||||
args = getArgs()
|
||||
@@ -1107,6 +1182,53 @@ def importDbBackup():
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
|
||||
def importDbBackupProgress():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
file = args['file']
|
||||
name = args['name']
|
||||
|
||||
cmd = 'cd '+mw.getServerDir()+'/mdserver-web && source bin/activate && '
|
||||
cmd += 'python3 '+mw.getServerDir()+'/mdserver-web/plugins/mysql/index.py import_db_backup_progress_bar {"file":"'+file+'","name":"'+name+'"}'
|
||||
return mw.returnJson(True, 'ok',cmd)
|
||||
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
def importDbBackupProgressBar():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
file = args['file']
|
||||
name = args['name']
|
||||
|
||||
file_path = mw.getRootDir() + '/backup/database/' + file
|
||||
file_path_sql = mw.getRootDir() + '/backup/database/' + file.replace('.gz', '')
|
||||
|
||||
if not os.path.exists(file_path_sql):
|
||||
cmd = 'cd ' + mw.getRootDir() + '/backup/database && gzip -d ' + file
|
||||
mw.execShell(cmd)
|
||||
|
||||
local_mode = recognizeDbMode()
|
||||
if local_mode == 'gtid':
|
||||
pdb = pMysqlDb()
|
||||
pdb.execute('reset master')
|
||||
|
||||
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
|
||||
sock = getSocketFile()
|
||||
|
||||
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p"' + pwd + \
|
||||
'" ' + name
|
||||
mysql_cmd_progress_bar = "pv -t -p " + file_path_sql + '|'+ mysql_cmd
|
||||
print(mysql_cmd_progress_bar)
|
||||
rdata = os.system(mysql_cmd_progress_bar)
|
||||
return ''
|
||||
|
||||
|
||||
def deleteDbBackup():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['filename', 'path'])
|
||||
@@ -3258,8 +3380,16 @@ if __name__ == "__main__":
|
||||
print(setDbBackup())
|
||||
elif func == 'import_db_backup':
|
||||
print(importDbBackup())
|
||||
elif func == 'import_db_backup_progress':
|
||||
print(importDbBackupProgress())
|
||||
elif func == 'import_db_backup_progress_bar':
|
||||
print(importDbBackupProgressBar())
|
||||
elif func == 'import_db_external':
|
||||
print(importDbExternal())
|
||||
elif func == 'import_db_external_progress':
|
||||
print(importDbExternalProgress())
|
||||
elif func == 'import_db_external_progress_bar':
|
||||
print(importDbExternalProgressBar())
|
||||
elif func == 'delete_db_backup':
|
||||
print(deleteDbBackup())
|
||||
elif func == 'get_db_backup_list':
|
||||
|
||||
@@ -929,6 +929,31 @@ function importBackup(file,name){
|
||||
});
|
||||
}
|
||||
|
||||
function importBackupProgress(file,name){
|
||||
myPost('import_db_backup_progress',{file:file,name:name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.open({
|
||||
title: "手动导入命令CMD【显示进度】",
|
||||
area: ['600px', '180px'],
|
||||
type:1,
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
btn:["复制","取消"],
|
||||
content: '<div class="pd15">\
|
||||
<div class="divtable">\
|
||||
<pre class="layui-code">'+rdata.data+'</pre>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
copyText(rdata.data);
|
||||
},
|
||||
yes:function(){
|
||||
copyText(rdata.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function importDbExternal(file,name){
|
||||
myPost('import_db_external',{file:file,name:name}, function(data){
|
||||
@@ -936,6 +961,31 @@ function importDbExternal(file,name){
|
||||
});
|
||||
}
|
||||
|
||||
function importDbExternalProgress(file,name){
|
||||
myPost('import_db_external_progress',{file:file,name:name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.open({
|
||||
title: "手动导入命令CMD【显示进度】",
|
||||
area: ['600px', '180px'],
|
||||
type:1,
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
btn:["复制","取消"],
|
||||
content: '<div class="pd15">\
|
||||
<div class="divtable">\
|
||||
<pre class="layui-code">'+rdata.data+'</pre>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
copyText(rdata.data);
|
||||
},
|
||||
yes:function(){
|
||||
copyText(rdata.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setLocalImport(db_name){
|
||||
|
||||
//上传文件
|
||||
@@ -991,6 +1041,7 @@ function setLocalImport(db_name){
|
||||
<td><span> ' + file_list[i]['time'] + '</span></td>\
|
||||
<td style="text-align: right;">\
|
||||
<a class="btlink" onclick="importDbExternal(\'' + file_list[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
|
||||
<a class="btlink" onclick="importDbExternalProgress(\'' + file_list[i]['name'] + '\',\'' +db_name+ '\')">导入进度</a> | \
|
||||
<a class="btlink del" index="'+i+'">删除</a>\
|
||||
</td>\
|
||||
</tr>';
|
||||
@@ -1014,7 +1065,7 @@ function setLocalImport(db_name){
|
||||
var layerIndex = layer.open({
|
||||
type: 1,
|
||||
title: "从文件导入数据",
|
||||
area: ['600px', '380px'],
|
||||
area: ['700px', '380px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
@@ -1060,7 +1111,7 @@ function setBackup(db_name){
|
||||
var layerIndex = layer.open({
|
||||
type: 1,
|
||||
title: "数据库备份详情",
|
||||
area: ['600px', '280px'],
|
||||
area: ['700px', '280px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
@@ -1114,6 +1165,7 @@ function setBackupReq(db_name, obj){
|
||||
<td><span> ' + rdata.data[i]['time'] + '</span></td>\
|
||||
<td style="text-align: right;">\
|
||||
<a class="btlink" onclick="importBackup(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
|
||||
<a class="btlink" onclick="importBackupProgress(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">导入进度</a> | \
|
||||
<a class="btlink" onclick="downloadBackup(\'' + rdata.data[i]['file'] + '\')">下载</a> | \
|
||||
<a class="btlink" onclick="delBackup(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">删除</a>\
|
||||
</td>\
|
||||
|
||||
@@ -16,7 +16,7 @@ function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)"
|
||||
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
|
||||
|
||||
|
||||
version=8.1.27
|
||||
version=8.1.28
|
||||
PHP_VER=81
|
||||
Install_php()
|
||||
{
|
||||
@@ -56,7 +56,7 @@ if [ ! -d $sourcePath/php/php${PHP_VER} ];then
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_file_ok=479e65c3f05714d4aace1370e617d78e49e996ec7a7579a5be47535be61f0658
|
||||
md5_file_ok=95d0b2e9466108fd750dab5c30a09e5c67f5ad2cb3b1ffb3625a038a755ad080
|
||||
if [ -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
md5_file=`sha256sum $sourcePath/php/php-${version}.tar.xz | awk '{print $1}'`
|
||||
if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
|
||||
@@ -16,7 +16,7 @@ function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)"
|
||||
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
|
||||
|
||||
|
||||
version=8.2.17
|
||||
version=8.2.18
|
||||
PHP_VER=82
|
||||
Install_php()
|
||||
{
|
||||
@@ -57,7 +57,7 @@ if [ ! -d $sourcePath/php/php${PHP_VER} ];then
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_file_ok=1cc4ef733ba58f6557db648012471f1916e5bac316303aa165535bedab08ee35
|
||||
md5_file_ok=44b306fc021e56441f691da6c3108788bd9e450f293b3bc70fcd64b08dd41a50
|
||||
if [ -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
md5_file=`sha256sum $sourcePath/php/php-${version}.tar.xz | awk '{print $1}'`
|
||||
if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
|
||||
@@ -15,7 +15,7 @@ function version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)"
|
||||
function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }
|
||||
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
|
||||
|
||||
version=8.3.4
|
||||
version=8.3.6
|
||||
PHP_VER=83
|
||||
Install_php()
|
||||
{
|
||||
@@ -56,7 +56,7 @@ if [ ! -d $sourcePath/php/php${PHP_VER} ];then
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_file_ok=39a337036a546e5c28aea76cf424ac172db5156bd8a8fd85252e389409a5ba63
|
||||
md5_file_ok=53c8386b2123af97626d3438b3e4058e0c5914cb74b048a6676c57ac647f5eae
|
||||
if [ -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
md5_file=`sha256sum $sourcePath/php/php-${version}.tar.xz | awk '{print $1}'`
|
||||
if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
|
||||
+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();
|
||||
|
||||
@@ -14,6 +14,7 @@ dnf install -y python3-devel
|
||||
dnf install -y python-devel
|
||||
dnf install -y crontabs
|
||||
dnf install -y mysql-devel
|
||||
dnf install -y pv
|
||||
|
||||
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
|
||||
if [ "$SSH_PORT" == "" ];then
|
||||
|
||||
@@ -21,6 +21,7 @@ yum install -y python-devel
|
||||
yum install -y curl-devel libmcrypt libmcrypt-devel
|
||||
yum install -y mysql-devel
|
||||
yum install -y expect
|
||||
yum install -y pv
|
||||
|
||||
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
|
||||
if [ "$SSH_PORT" == "" ];then
|
||||
|
||||
@@ -40,6 +40,8 @@ echo y | pacman -Sy rpcsvc-proto
|
||||
echo y | pacman -Sy lemon
|
||||
echo y | pacman -Sy which
|
||||
echo y | pacman -Sy expect
|
||||
echo y | pacman -Sy pv
|
||||
|
||||
|
||||
## gd start
|
||||
echo y | pacman -Sy gd
|
||||
|
||||
@@ -31,6 +31,7 @@ yum install -y libmcrypt
|
||||
yum install -y libmcrypt-devel
|
||||
yum install -y mysql-devel
|
||||
yum install -y expect
|
||||
yum install -y pv
|
||||
|
||||
|
||||
# if [ -f /usr/sbin/iptables ];then
|
||||
|
||||
@@ -56,6 +56,7 @@ apt-get update -y
|
||||
apt install -y wget curl lsof unzip tar cron expect locate lrzsz
|
||||
apt install -y rar
|
||||
apt install -y unrar
|
||||
apt install -y pv
|
||||
apt install -y python3-pip python3-dev python3-venv
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ yum install -y libmcrypt
|
||||
yum install -y libmcrypt-devel
|
||||
yum install -y mysql-devel
|
||||
yum install -y expect
|
||||
yum install -y pv
|
||||
|
||||
|
||||
# if [ -f /usr/sbin/iptables ];then
|
||||
|
||||
@@ -73,6 +73,7 @@ yum install -y epel-release
|
||||
|
||||
yum install -y libevent libevent-devel zip libmcrypt libmcrypt-devel
|
||||
yum install -y rar unrar
|
||||
yum install -y pv
|
||||
yum install -y gcc libffi-devel python-devel openssl-devel
|
||||
yum install -y libmcrypt libmcrypt-devel python3-devel
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ pkg install -y harfbuzz
|
||||
pkg install -y libevent
|
||||
pkg install -y pidof
|
||||
pkg install -y pstree
|
||||
pkg install -y pv
|
||||
|
||||
# curl https://sh.rustup.rs -sSf | sh
|
||||
pkg install -y rust
|
||||
|
||||
@@ -22,7 +22,7 @@ if [ "$?" != "0" ];then
|
||||
brew install mysql
|
||||
fi
|
||||
|
||||
|
||||
brew install pv
|
||||
brew install libzip bzip2 gcc openssl re2c cmake
|
||||
brew install librdkafka
|
||||
brew install coreutils libxml2 xml2
|
||||
|
||||
@@ -28,6 +28,7 @@ zypper install -y libevent-devel
|
||||
zypper install -y libtirpc-devel
|
||||
zypper install -y rpcgen
|
||||
zypper install -y expect
|
||||
zypper install -y pv
|
||||
|
||||
zypper install -y libzip libzip-devel
|
||||
zypper install -y unrar rar
|
||||
|
||||
@@ -184,6 +184,7 @@ if [ "$VERSION_ID" -ge "8" ];then
|
||||
oniguruma oniguruma-devel patch pcre pcre-devel perl perl-Data-Dumper perl-devel procps psmisc python3-devel \
|
||||
openssl openssl-devel patchelf libargon2-devel\
|
||||
ImageMagick ImageMagick-devel libyaml-devel \
|
||||
pv \
|
||||
readline-devel rpcgen sqlite-devel rar unrar tar unzip vim-minimal wget zip zlib zlib-devel;
|
||||
do
|
||||
# dnf --enablerepo=remi,appstream,baseos,epel,extras,powertools install -y oniguruma5php-devel
|
||||
@@ -203,6 +204,7 @@ else
|
||||
libwebp libwebp-devel libxml2 libxml2-devel libxslt libxslt-devel libzip libzip-devel libzstd-devel \
|
||||
make mysql-devel ncurses ncurses-devel net-tools oniguruma oniguruma-devel openldap openldap-devel \
|
||||
openssl openssl-devel patch pcre pcre-devel perl perl-Data-Dumper perl-devel psmisc python-devel \
|
||||
pv \
|
||||
python3-devel python3-pip re2c readline-devel rpcgen sqlite-devel tar unzip rar unrar vim-minimal vixie-cron \
|
||||
wget zip zlib zlib-devel ImageMagick ImageMagick-devel libyaml-devel patchelf libargon2-devel;
|
||||
do
|
||||
|
||||
@@ -15,6 +15,7 @@ sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
|
||||
|
||||
yum install -y wget lsof
|
||||
yum install -y unrar rar
|
||||
yum install -y pv
|
||||
yum install -y python3-devel
|
||||
yum install -y crontabs
|
||||
yum install -y expect
|
||||
|
||||
@@ -18,7 +18,7 @@ apt install -y python3-pip
|
||||
apt install -y python3-venv
|
||||
apt install -y python3-dev
|
||||
apt install -y expect
|
||||
|
||||
apt install -y pv
|
||||
apt install -y cron
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user