diff --git a/plugins/mysql/index.html b/plugins/mysql/index.html index 1789a0965..78ec5cd5c 100755 --- a/plugins/mysql/index.html +++ b/plugins/mysql/index.html @@ -12,6 +12,7 @@

性能优化

日志

慢日志

+

BINLOG

管理列表

主从配置

diff --git a/plugins/mysql/index.py b/plugins/mysql/index.py index 1f5989d5e..459a830d0 100755 --- a/plugins/mysql/index.py +++ b/plugins/mysql/index.py @@ -293,6 +293,14 @@ def getDataDir(): return tmp.groups()[0].strip() +def getLogBinName(): + file = getConf() + content = mw.readFile(file) + rep = 'log-bin\s*=\s*(.*)' + tmp = re.search(rep, content) + return tmp.groups()[0].strip() + + def getPidFile(): file = getConf() content = mw.readFile(file) @@ -333,6 +341,68 @@ def binLog(): return mw.returnJson(True, '设置成功!') +def binLogList(): + args = getArgs() + data = checkArgs(args, ['page', 'page_size', 'tojs']) + if not data[0]: + return data[1] + + page = int(args['page']) + page_size = int(args['page_size']) + + data_dir = getDataDir() + log_bin_name = getLogBinName() + + alist = os.listdir(data_dir) + log_bin_l = [] + for x in range(len(alist)): + f = alist[x] + t = {} + if f.startswith(log_bin_name) and f != (log_bin_name + '.index'): + abspath = data_dir + '/' + f + t['name'] = f + t['size'] = os.path.getsize(abspath) + t['time'] = mw.getDataFromInt(os.path.getctime(abspath)) + log_bin_l.append(t) + + # print(log_bin_l) + # print(data_dir, log_bin_name) + + count = len(log_bin_l) + + page_start = (page - 1) * page_size + page_end = page_start + page_size + if page_end > count: + page_end = count + + data = {} + page_args = {} + page_args['count'] = count + page_args['p'] = page + page_args['row'] = page_size + page_args['tojs'] = args['tojs'] + data['page'] = mw.getPage(page_args) + data['data'] = log_bin_l[page_start:page_end] + + return mw.getJson(data) + + +def binLogListLook(): + args = getArgs() + data = checkArgs(args, ['file']) + if not data[0]: + return data[1] + + data_dir = getDataDir() + my_bin = getServerDir() + '/bin' + my_binlog_cmd = my_bin + '/mysqlbinlog' + + cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \ + data_dir + '/' + args['file'] + '|tail -50' + + print(cmd) + + def cleanBinLog(): db = pMysqlDb() cleanTime = time.strftime('%Y-%m-%d %H:%i:%s', time.localtime()) @@ -3075,6 +3145,10 @@ if __name__ == "__main__": print(getConf()) elif func == 'bin_log': print(binLog()) + elif func == 'binlog_list': + print(binLogList()) + elif func == 'binlog_look': + print(binLogListLook()) elif func == 'clean_bin_log': print(cleanBinLog()) elif func == 'error_log': diff --git a/plugins/mysql/index_mysql.py b/plugins/mysql/index_mysql.py new file mode 100644 index 000000000..31f132b87 --- /dev/null +++ b/plugins/mysql/index_mysql.py @@ -0,0 +1,74 @@ +# coding:utf-8 + +import sys +import io +import os +import time +import subprocess +import re +import json + +sys.path.append(os.getcwd() + "/class/core") +import mw + + +if mw.isAppleSystem(): + cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\'' + info = mw.execShell(cmd) + p = "/usr/local/lib/" + info[0].strip() + "/site-packages" + sys.path.append(p) + + +app_debug = False +if mw.isAppleSystem(): + app_debug = True + + +def getPluginName(): + return 'mysql' + + +def getPluginDir(): + return mw.getPluginDir() + '/' + getPluginName() + + +def getSPluginDir(): + return '/www/server/mdserver-web/plugins/' + getPluginName() + + +def getServerDir(): + return mw.getServerDir() + '/' + getPluginName() + + +def getConf(): + path = getServerDir() + '/etc/my.cnf' + return path + + +def getDataDir(): + file = getConf() + content = mw.readFile(file) + rep = 'datadir\s*=\s*(.*)' + tmp = re.search(rep, content) + return tmp.groups()[0].strip() + + +def binLogListLook(args): + + file = args['file'] + line = args['line'] + + data_dir = getDataDir() + my_bin = getServerDir() + '/bin' + my_binlog_cmd = my_bin + '/mysqlbinlog' + + cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \ + data_dir + '/' + file + '|tail -' + line + + data = mw.execShell(cmd) + + rdata = {} + rdata['cmd'] = cmd + rdata['data'] = data[0] + + return rdata diff --git a/plugins/mysql/js/mysql.js b/plugins/mysql/js/mysql.js index c02528ac3..dc8274fca 100755 --- a/plugins/mysql/js/mysql.js +++ b/plugins/mysql/js/mysql.js @@ -59,6 +59,63 @@ function myAsyncPost(method,args){ return syncPost('/plugins/run', {name:'mysql', func:method, args:_args}); } + +function myPostCallbak(method, version, args,callback){ + var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 }); + + var req_data = {}; + req_data['name'] = 'mysql'; + req_data['func'] = method; + req_data['script']='index_mysql'; + args['version'] = version; + + + if (typeof(args) == 'string' && args == ''){ + req_data['args'] = JSON.stringify(toArrayObject(args)); + } else { + req_data['args'] = JSON.stringify(args); + } + + $.post('/plugins/callback', req_data, function(data) { + layer.close(loadT); + if (!data.status){ + layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']}); + return; + } + + if(typeof(callback) == 'function'){ + callback(data); + } + },'json'); +} + +function myPostCallbakN(method, version, args,callback){ + + var req_data = {}; + req_data['name'] = 'mysql'; + req_data['func'] = method; + req_data['script']='index_mysql'; + args['version'] = version; + + + if (typeof(args) == 'string' && args == ''){ + req_data['args'] = JSON.stringify(toArrayObject(args)); + } else { + req_data['args'] = JSON.stringify(args); + } + + $.post('/plugins/callback', req_data, function(data) { + if (!data.status){ + layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']}); + return; + } + + if(typeof(callback) == 'function'){ + callback(data); + } + },'json'); +} + function vaildPhpmyadmin(url,username,password){ // console.log("Authorization: Basic " + btoa(username + ":" + password)); $.ajax({ @@ -1163,6 +1220,120 @@ function dbList(page, search){ } +function myBinRollingLogs(_name, func, _args, line){ + + var file_line = 100; + if ( typeof(line) != 'undefined' ){ + file_line = line; + } + + var reqTimer = null; + + function requestLogs(func,file,line){ + myPostCallbakN(func,'',{'file':file,"line":line}, function(rdata){ + var data = rdata.data.data; + if(data == '') { + data = '当前没有日志!'; + } + + var ebody = ''; + $("#my_rolling_logs").html(ebody); + var ob = document.getElementById('roll_info_log'); + ob.scrollTop = ob.scrollHeight; + }); + } + + + layer.open({ + type: 1, + title: _name + '日志', + area: '640px', + end: function(){ + if (reqTimer){ + clearInterval(reqTimer); + } + }, + content:'
\ + \ + \ + \ +
', + success:function(){ + var fileName = _args['file']; + // requestLogs(func,fileName,file_line); + // reqTimer = setInterval(function(){ + // requestLogs(func,fileName,file_line); + // },3000); + } + }); +} +function myBinLogsRender(page){ + var _data = {}; + if (typeof(page) =='undefined'){ + var page = 1; + } + + _data['page'] = page; + _data['page_size'] = 10; + _data['tojs'] = 'myBinLogsRender'; + myPost('binlog_list', _data, function(data){ + var rdata = $.parseJSON(data.data); + // console.log(rdata); + var list = ''; + for(i in rdata.data){ + list += ''; + + list += '' + rdata.data[i]['name'] +''; + list += '' + toSize(rdata.data[i]['size'])+''; + list += '' + rdata.data[i]['time'] +''; + + + list += ''; + list += '查看 | '; + list += '解码查看'; + list += ''; + } + + $("#binlog_list tbody").html(list); + $('#binlog_page').html(rdata.page); + + + $('#binlog_list .look').click(function(){ + var i = $(this).data('index'); + var file = rdata.data[i]['name']; + + myBinRollingLogs('查看','binLogListLook',{'file':file },100); + // myPostCallbak('binLogListLook','',{'file':file}, function(rdata){ + // console.log(rdata); + // }); + }); + + + }); +} + +function myBinLogs(){ + var con = '
\ + \ + \ +
\ +
\ + \ + \ + \ + \ + \ + \ + \ +
文件名称大小时间操作
\ +
\ +
\ +
\ +
'; + $(".soft-man-con").html(con); + myBinLogsRender(1); +} + function myLogs(){ myPost('bin_log', {status:1}, function(data){