mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-18 23:45:52 +08:00
update
This commit is contained in:
@@ -90,7 +90,7 @@ class nosqlMySQL():
|
||||
keys = ["bind_ip", "port"]
|
||||
|
||||
result['host'] = '127.0.0.1'
|
||||
rep = 'port\s*=\s*(.*)'
|
||||
rep = r'port\s*=\s*(.*)'
|
||||
|
||||
port_re = re.search(rep, my_content)
|
||||
if port_re:
|
||||
@@ -98,7 +98,7 @@ class nosqlMySQL():
|
||||
else:
|
||||
result['port'] = 3306
|
||||
|
||||
socket_rep = 'socket\s*=\s*(.*)'
|
||||
socket_rep = r'socket\s*=\s*(.*)'
|
||||
socket_re = re.search(socket_rep, my_content)
|
||||
if socket_re:
|
||||
result['socket'] = socket_re.groups()[0].strip()
|
||||
@@ -281,6 +281,88 @@ class nosqlMySQLCtr():
|
||||
rdata['list'] = result
|
||||
return mw.returnData(True,'ok', rdata)
|
||||
|
||||
def getNetRow(self, my_instance):
|
||||
row = {}
|
||||
|
||||
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Com_select'")
|
||||
row['select'] = data['Value']
|
||||
|
||||
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Com_insert'")
|
||||
row['insert'] = data['Value']
|
||||
|
||||
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Com_update'")
|
||||
row['update'] = data['Value']
|
||||
|
||||
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Com_delete'")
|
||||
row['delete'] = data['Value']
|
||||
|
||||
|
||||
|
||||
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Bytes_received'")
|
||||
row['recv_bytes'] = data['Value']
|
||||
|
||||
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Bytes_sent'")
|
||||
row['send_bytes'] = data['Value']
|
||||
return row
|
||||
|
||||
|
||||
def getNetList(self, args):
|
||||
from datetime import datetime
|
||||
sid = args['sid']
|
||||
my_instance = self.getInstanceBySid(sid).conn()
|
||||
if my_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
rdata = []
|
||||
row = {}
|
||||
row1 = self.getNetRow(my_instance)
|
||||
# 等待1秒
|
||||
time.sleep(1)
|
||||
row2 = self.getNetRow(my_instance)
|
||||
|
||||
data = my_instance.find("SHOW GLOBAL VARIABLES LIKE 'max_connections'")
|
||||
row['max_conn'] = data['Value']
|
||||
|
||||
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Threads_connected'")
|
||||
row['conn'] = data['Value']
|
||||
|
||||
current_time = datetime.now()
|
||||
row['current_time'] = current_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
row['select'] = int(row2['select']) - int(row1['select'])
|
||||
row['insert'] = int(row2['insert']) - int(row1['insert'])
|
||||
row['update'] = int(row2['update']) - int(row1['update'])
|
||||
row['delete'] = int(row2['delete']) - int(row1['delete'])
|
||||
|
||||
recv_per_second = int(row2['recv_bytes']) - int(row1['recv_bytes'])
|
||||
send_per_second = int(row2['send_bytes']) - int(row1['send_bytes'])
|
||||
|
||||
# 将每秒接收和发送数据量从字节转换为兆比特
|
||||
row['recv_mbps'] = "{:.2f}".format(recv_per_second * 8 / 1000000) + " MBit/s"
|
||||
row['send_mbps'] = "{:.2f}".format(send_per_second * 8 / 1000000) + " MBit/s"
|
||||
|
||||
rdata.append(row)
|
||||
return mw.returnData(True, 'ok', rdata)
|
||||
|
||||
|
||||
def getTopnList(self, args):
|
||||
sid = args['sid']
|
||||
my_instance = self.getInstanceBySid(sid).conn()
|
||||
if my_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
is_performance_schema = my_instance.find("SELECT @@performance_schema")
|
||||
if is_performance_schema["@@performance_schema"] == 0:
|
||||
msg = "performance_schema参数未开启。\n"
|
||||
msg += "在my.cnf配置文件里添加performance_schema=1,并重启mysqld进程生效。"
|
||||
return mw.returnData(False, msg)
|
||||
|
||||
my_instance.execute("SET @sys.statement_truncate_len=4096")
|
||||
data = my_instance.query("select query,db,last_seen,exec_count,max_latency,avg_latency from sys.statement_analysis order by exec_count desc, last_seen desc limit 10")
|
||||
if data is None:
|
||||
return mw.returnData(False, "查询失败!")
|
||||
return mw.returnData(True, 'ok', data)
|
||||
|
||||
# ---------------------------------- run ----------------------------------
|
||||
# 获取 mysql 列表
|
||||
def get_db_list(args):
|
||||
@@ -308,6 +390,19 @@ def get_stats_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.showStatsList(args)
|
||||
|
||||
# 查询执行次数最频繁的前N条SQL语句
|
||||
def get_topn_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.getTopnList(args)
|
||||
|
||||
# MySQL服务器的QPS/TPS/网络带宽指标
|
||||
def get_net_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.getNetList(args)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 测试
|
||||
def test(args):
|
||||
|
||||
@@ -51,9 +51,11 @@
|
||||
<input name="mysql_field_value" type="text" class="bt-input-text" placeholder="请输入查找内容">
|
||||
</div>
|
||||
|
||||
<button type="button" class="mysql_find btn btn-success btn-sm mr5 ml5" style="float:right;">
|
||||
<span>查找</span>
|
||||
</button>
|
||||
|
||||
<div style="float:left;">
|
||||
<button type="button" class="mysql_find btn btn-success btn-sm mr5 ml5" >查找</button>
|
||||
<button id="mysql_common" type="button" class="mysql_find btn btn-success btn-sm mr5 ml5">常用功能</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -78,6 +80,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr style="border:none;" />
|
||||
|
||||
<div class="col-md-12" style="padding-left: 3px;">
|
||||
<div id="mysql_list_tab" style="padding-top:0px;">
|
||||
<div class="tab-nav">
|
||||
|
||||
@@ -267,6 +267,185 @@ function initTabMySQL(){
|
||||
var name = $(this).data('name');
|
||||
mysqlRunMysqlTab(name);
|
||||
});
|
||||
|
||||
mysqlCommonFunc();
|
||||
}
|
||||
|
||||
function mysqlCommonFuncMysqlNSQL(){
|
||||
function renderSQL(){
|
||||
var sid = mysqlGetSid();
|
||||
myPostCBN('get_topn_list',{'sid':sid} ,function(rdata){
|
||||
var data = rdata.data;
|
||||
if (data['status']){
|
||||
var items = data.data;
|
||||
var tbody = '';
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var t = '<tr>';
|
||||
t += '<td>'+items[i].query+'</td>';
|
||||
t += '<td>'+items[i].db+'</td>';
|
||||
t += '<td>'+items[i].last_seen+'</td>';
|
||||
t += '<td>'+items[i].exec_count+'</td>';
|
||||
t += '<td>'+items[i].max_latency+'</td>';
|
||||
t += '<td>'+items[i].avg_latency+'</td>';
|
||||
t += '</tr>';
|
||||
tbody += t;
|
||||
}
|
||||
$('#topn_list tbody').html(tbody);
|
||||
} else {
|
||||
layer.msg(data.msg,{icon:2});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var sql_timer = null;
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: "查询执行次数最频繁的前N条SQL语句",
|
||||
area: ['1200px', '500px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="bt-form pd20 divtable taskdivtable">\
|
||||
<div class="mr20 pull-left" style="border-right: 1px solid #ccc; padding-right: 20px;">\
|
||||
<div class="ss-text pull-left">\
|
||||
<em>实时监控</em>\
|
||||
<div class="ssh-item">\
|
||||
<input class="btswitch btswitch-ios" id="real_time_monitoring" type="checkbox">\
|
||||
<label id="real_time_label" class="btswitch-btn" for="real_time_monitoring"></label>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<hr />\
|
||||
<table class="table table-hover" id="topn_list">\
|
||||
<thead>\
|
||||
<th>SQL</th>\
|
||||
<th style="width:100px;">数据名</th>\
|
||||
<th>最近时间</th>\
|
||||
<th style="width:100px;">总次数</th>\
|
||||
<th style="width:100px;">最大时间</th>\
|
||||
<th style="width:100px;">平均时间</th>\
|
||||
</thead>\
|
||||
<tbody></tbody>\
|
||||
</table>\
|
||||
</div>',
|
||||
success:function(i,l){
|
||||
renderSQL();
|
||||
|
||||
$('#real_time_label').click(function(){
|
||||
sql_timer = setInterval(function(){
|
||||
var t = $('#real_time_monitoring').is(':checked');
|
||||
if (t){
|
||||
renderSQL();
|
||||
} else{
|
||||
clearInterval(sql_timer);
|
||||
}
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function mysqlCommonFuncMysqlNet(){
|
||||
function renderSQL(){
|
||||
var sid = mysqlGetSid();
|
||||
myPostCBN('get_net_list',{'sid':sid} ,function(rdata){
|
||||
var data = rdata.data;
|
||||
if (data['status']){
|
||||
var items = data.data;
|
||||
var tbody = '';
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var t = '<tr>';
|
||||
t += '<td>'+items[i]['current_time']+'</td>';
|
||||
t += '<td>'+items[i]['select']+'</td>';
|
||||
t += '<td>'+items[i]['insert']+'</td>';
|
||||
t += '<td>'+items[i]['update']+'</td>';
|
||||
t += '<td>'+items[i]['delete']+'</td>';
|
||||
t += '<td>'+items[i]['conn']+'</td>';
|
||||
t += '<td>'+items[i]['max_conn']+'</td>';
|
||||
t += '<td>'+items[i]['recv_mbps']+'</td>';
|
||||
t += '<td>'+items[i]['send_mbps']+'</td>';
|
||||
t += '</tr>';
|
||||
tbody += t;
|
||||
}
|
||||
$('#net_list tbody').html(tbody);
|
||||
} else {
|
||||
layer.msg(data.msg,{icon:2});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var sql_timer = null;
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: "MySQL服务器的QPS/TPS/网络带宽指标",
|
||||
area: ['700px', '220px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="bt-form pd20 divtable taskdivtable">\
|
||||
<div class="mr20 pull-left" style="border-right: 1px solid #ccc; padding-right: 20px;">\
|
||||
<div class="ss-text pull-left">\
|
||||
<em>实时监控</em>\
|
||||
<div class="ssh-item">\
|
||||
<input class="btswitch btswitch-ios" id="real_qps_monitoring" type="checkbox">\
|
||||
<label id="real_qps_label" class="btswitch-btn" for="real_qps_monitoring"></label>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<hr />\
|
||||
<table class="table table-hover" id="net_list">\
|
||||
<thead>\
|
||||
<th style="width:160px;">时间</th>\
|
||||
<th style="width:50px;">Select</th>\
|
||||
<th style="width:50px;">Insert</th>\
|
||||
<th style="width:50px;">Update</th>\
|
||||
<th style="width:50px;">Delete</th>\
|
||||
<th style="width:50px;">Conn</th>\
|
||||
<th style="width:50px;">Max_conn</th>\
|
||||
<th style="width:90px;">Recv</th>\
|
||||
<th style="width:90px;">Send</th>\
|
||||
</thead>\
|
||||
<tbody></tbody>\
|
||||
</table>\
|
||||
</div>',
|
||||
success:function(i,l){
|
||||
renderSQL();
|
||||
|
||||
$('#real_qps_label').click(function(){
|
||||
sql_timer = setInterval(function(){
|
||||
var t = $('#real_qps_monitoring').is(':checked');
|
||||
if (t){
|
||||
renderSQL();
|
||||
} else{
|
||||
clearInterval(sql_timer);
|
||||
}
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function mysqlCommonFunc(){
|
||||
$('#mysql_common').click(function(){
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: "MySQL常用功能",
|
||||
area: ['600px', '400px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="bt-form pd20">\
|
||||
<button id="mysql_top_nsql" type="button" class="btn btn-default btn-sm">查询执行次数最频繁的前N条SQL语句</button>\
|
||||
<button id="mysql_net_stat" type="button" class="btn btn-default btn-sm">MySQL服务器的QPS/TPS/网络带宽指标</button>\
|
||||
</div>',
|
||||
success:function(i,l){
|
||||
$('#mysql_top_nsql').click(function(){
|
||||
mysqlCommonFuncMysqlNSQL();
|
||||
});
|
||||
|
||||
$('#mysql_net_stat').click(function(){
|
||||
mysqlCommonFuncMysqlNet();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function mysqlRunMysqlTab(name){
|
||||
|
||||
@@ -506,25 +506,25 @@ function get_resource_list() {
|
||||
buildRealProcess()
|
||||
var tbody_tr = createProcessTable(true);
|
||||
var tbody = '<thead>\
|
||||
<tr style="cursor: pointer;">\
|
||||
<th style="width:120px;" class="pro_name pro_ps" onclick="get_process_list(\'ps\',\'' + res_list[reverse] + '\')">应用名称</th>\
|
||||
<th class="pro_pid" onclick="get_process_list(\'pid\',\'' + res_list[reverse] + '\')">PID</th>\
|
||||
<th style="width:50px;"class="pro_threads" onclick="get_process_list(\'threads\',\'True\')">线程</th>\
|
||||
<th style="width:60px;" class="pro_user" onclick="get_process_list(\'user\',\'' + res_list[reverse] + '\')">用户</th>\
|
||||
<th style="width:70px;" class="pro_cpu_percent" onclick="get_process_list(\'cpu_percent\',\'True\')">CPU</th>\
|
||||
<th style="width:70px;" class="pro_memory_used" onclick="get_process_list(\'memory_used\',\'True\')">内存</th>\
|
||||
<th style="width:70px;" class="pro_io_read_speed" onclick="get_process_list(\'io_read_speed\',\'True\')">io读</th>\
|
||||
<th style="width:70px;" class="pro_io_write_speed" onclick="get_process_list(\'io_write_speed\',\'True\')">io写</th>\
|
||||
<th style="width:70px;" class="pro_up" onclick="get_process_list(\'up\',\'True\')">上行</th>\
|
||||
<th style="width:70px;" class="pro_down" onclick="get_process_list(\'down\',\'True\')">下行</th>\
|
||||
<th style="width:50px;" class="pro_connects" onclick="get_process_list(\'connects\',\'True\')">连接</th>\
|
||||
<th style="width:50px;" class="pro_status" onclick="get_process_list(\'status\',\'' + res_list[reverse] + '\')">状态</th>\
|
||||
<th style="width:50px;cursor:text">操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody>' + tbody_tr + '</tbody>'
|
||||
$('#taskResourceTable').html(tbody);
|
||||
$(".table-cont").css("height", "220px");
|
||||
<tr style="cursor: pointer;">\
|
||||
<th style="width:120px;" class="pro_name pro_ps" onclick="get_process_list(\'ps\',\'' + res_list[reverse] + '\')">应用名称</th>\
|
||||
<th class="pro_pid" onclick="get_process_list(\'pid\',\'' + res_list[reverse] + '\')">PID</th>\
|
||||
<th style="width:50px;"class="pro_threads" onclick="get_process_list(\'threads\',\'True\')">线程</th>\
|
||||
<th style="width:60px;" class="pro_user" onclick="get_process_list(\'user\',\'' + res_list[reverse] + '\')">用户</th>\
|
||||
<th style="width:70px;" class="pro_cpu_percent" onclick="get_process_list(\'cpu_percent\',\'True\')">CPU</th>\
|
||||
<th style="width:70px;" class="pro_memory_used" onclick="get_process_list(\'memory_used\',\'True\')">内存</th>\
|
||||
<th style="width:70px;" class="pro_io_read_speed" onclick="get_process_list(\'io_read_speed\',\'True\')">io读</th>\
|
||||
<th style="width:70px;" class="pro_io_write_speed" onclick="get_process_list(\'io_write_speed\',\'True\')">io写</th>\
|
||||
<th style="width:70px;" class="pro_up" onclick="get_process_list(\'up\',\'True\')">上行</th>\
|
||||
<th style="width:70px;" class="pro_down" onclick="get_process_list(\'down\',\'True\')">下行</th>\
|
||||
<th style="width:50px;" class="pro_connects" onclick="get_process_list(\'connects\',\'True\')">连接</th>\
|
||||
<th style="width:50px;" class="pro_status" onclick="get_process_list(\'status\',\'' + res_list[reverse] + '\')">状态</th>\
|
||||
<th style="width:50px;cursor:text">操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody>' + tbody_tr + '</tbody>';
|
||||
$('#taskResourceTable').html(tbody);
|
||||
$(".table-cont").css("height", "220px");
|
||||
})
|
||||
|
||||
$("#load_average").html('')
|
||||
|
||||
+7
-1
@@ -119,6 +119,12 @@ class ORM:
|
||||
print(e)
|
||||
return True
|
||||
|
||||
def find(self, sql):
|
||||
d = self.query(sql)
|
||||
if d is not None:
|
||||
return d[0]
|
||||
return None
|
||||
|
||||
def query(self, sql):
|
||||
# 执行SQL语句返回数据集
|
||||
if not self.__Conn():
|
||||
@@ -132,7 +138,7 @@ class ORM:
|
||||
self.__Close()
|
||||
return result
|
||||
except Exception as ex:
|
||||
return ex
|
||||
return None
|
||||
|
||||
def __Close(self):
|
||||
# 关闭连接
|
||||
|
||||
Reference in New Issue
Block a user