Compare commits

..
40 Commits
Author SHA1 Message Date
Mr Chen a6a3cf7882 Merge pull request #568 from midoks/dev
0.16.8
2024-05-10 15:34:21 +08:00
Mr Chen a1afe5e846 0.16.8
- 首页对网络/磁盘IO进行更细致的展示。
2024-05-10 15:30:49 +08:00
Mr Chen 594e8c4b2b update 2024-05-10 14:36:38 +08:00
Mr Chen cc015bad61 update 2024-05-10 14:35:51 +08:00
Mr Chen bc9461dea6 update 2024-05-10 13:32:46 +08:00
Mr Chen 0a25598c15 Update config_api.py 2024-05-10 12:14:05 +08:00
Mr Chen 7a9a8a08b6 Update index.js 2024-05-10 12:13:51 +08:00
Mr Chen 8eb728defa index加入io统计展示 2024-05-10 12:04:21 +08:00
Mr Chen 7f8ffbf178 Update site.css 2024-05-10 04:36:43 +08:00
Mr Chen cb0027e903 Update system_api.py 2024-05-10 04:23:48 +08:00
Mr Chen e0ebdd922d Update site.css 2024-05-10 02:16:49 +08:00
Mr Chen d6f43a86c9 Update system_api.py 2024-05-10 02:16:39 +08:00
Mr Chen dfe7becdb1 Update system_api.py 2024-05-09 23:43:16 +08:00
Mr Chen 57f4162cb8 Update mongodb.js 2024-05-09 01:08:14 +08:00
Mr Chen a9ce4f2e23 Update mongodb.js 2024-05-09 01:05:03 +08:00
Mr Chen b501d62d91 Update mongodb.js 2024-05-09 01:03:41 +08:00
Mr Chen 45ffba1559 Merge pull request #567 from midoks/dev
mysql手动导入大文件sql
2024-05-08 17:02:59 +08:00
Mr Chen 28d0fbe106 手动导入大文件sql 2024-05-08 17:01:58 +08:00
Mr Chen eeb8fee3b3 Merge pull request #566 from midoks/dev
日志清理-改成每隔7天
2024-05-08 12:59:59 +08:00
Mr Chen 0e1fbdcfb9 update 2024-05-08 12:58:55 +08:00
Mr Chen df2744816b Merge pull request #565 from midoks/dev
php更新和安装脚本加入pv命令
2024-05-08 12:34:20 +08:00
Mr Chen 862c09778a Update euler.sh 2024-05-08 12:32:52 +08:00
Mr Chen 8f9a1888ff update 2024-05-08 12:32:37 +08:00
Mr Chen 66351dc3a7 update 2024-05-08 12:28:50 +08:00
Mr Chen 55c4709c93 Merge pull request #564 from midoks/dev
日志清理优化
2024-05-08 01:33:02 +08:00
Mr Chen e27ae42270 Update index.py 2024-05-08 01:27:23 +08:00
Mr Chen 70805de98e Update index.py 2024-05-08 01:26:43 +08:00
Mr Chen c0e09e43a2 Update index.py 2024-05-08 01:25:58 +08:00
Mr Chen b69a32c81f Update index.py 2024-05-08 01:20:29 +08:00
Mr Chen 2431833cce Update index.py 2024-05-08 01:19:53 +08:00
Mr Chen a85d8ec429 Update index.html 2024-05-08 01:15:59 +08:00
Mr Chen ce5a6edeea Update tool_task.py 2024-05-08 01:13:34 +08:00
Mr Chen aa195dea2c Update tool_task.py 2024-05-08 00:52:51 +08:00
Mr Chen 840a3c5911 Update layout.html 2024-05-08 00:27:09 +08:00
Mr Chen ca87ab78b3 Update layout.html 2024-05-08 00:11:04 +08:00
Mr Chen d9fc411168 Update layout.html 2024-05-08 00:00:37 +08:00
Mr Chen e468ab16eb Merge pull request #563 from midoks/dev
细节优化
2024-05-07 20:26:43 +08:00
Mr Chen c545062d07 Update index.py 2024-05-07 20:24:05 +08:00
Mr Chen e620fd67e3 Merge pull request #562 from midoks/dev
mongodb删除保护
2024-05-07 20:18:53 +08:00
Mr Chen aa9a412e9a mongodb删除保护 2024-05-07 20:18:23 +08:00
31 changed files with 1175 additions and 162 deletions
+2 -2
View File
@@ -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安装地址
+1 -1
View File
@@ -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
View File
@@ -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(
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+11 -1
View File
@@ -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':
+1
View File
@@ -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",
+1 -1
View File
@@ -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>';
}
+130
View File
@@ -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':
+54 -2
View File
@@ -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>\
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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>&nbsp;&nbsp;<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>&nbsp;&nbsp;<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();
}
}
+11
View File
@@ -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,'');
}
+106
View File
@@ -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;
}
+40 -10
View File
@@ -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();
+1
View File
@@ -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
+1
View File
@@ -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
+2
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+1 -1
View File
@@ -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
+1
View File
@@ -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
+2
View File
@@ -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
+1
View File
@@ -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
+1 -1
View File
@@ -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