diff --git a/plugins/mysql/js/mysql.js b/plugins/mysql/js/mysql.js index afc6c6030..c83ce1be0 100755 --- a/plugins/mysql/js/mysql.js +++ b/plugins/mysql/js/mysql.js @@ -82,7 +82,7 @@ function runInfo(){
\ - ' + lan.soft.mysql_log_bin + ' ' + ToSize(rdata.msg) + '\ - \ -
' + lan.soft.mysql_log_err + '
\ - \ - ' - - $(".soft-man-con").html(limitCon); - - //获取错误日志 - $.post('/database?action=GetErrorLog', "", function(error_body) { - if (error_body.status === false) { - layer.msg(error_body.msg, { icon: 5 }); - error_body = lan.soft.mysql_log_ps1; - } - if (error_body == "") error_body = lan.soft.mysql_log_ps1; - $("#error_log").text(error_body); - var ob = document.getElementById('error_log'); - ob.scrollTop = ob.scrollHeight; - }); - }); -} - //数据库配置状态 function myPerfOpt() { diff --git a/plugins/sphinx/class/sphinxapi.py b/plugins/sphinx/class/sphinxapi.py new file mode 100644 index 000000000..88f5afde4 --- /dev/null +++ b/plugins/sphinx/class/sphinxapi.py @@ -0,0 +1,1256 @@ +# +# $Id$ +# +# Python version of Sphinx searchd client (Python API) +# +# Copyright (c) 2006, Mike Osadnik +# Copyright (c) 2006-2016, Andrew Aksyonoff +# Copyright (c) 2008-2016, Sphinx Technologies Inc +# All rights reserved +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library General Public License. You should +# have received a copy of the LGPL license along with this program; if you +# did not, you can find it at http://www.gnu.org/ +# +# WARNING!!! +# +# As of 2015, we strongly recommend to use either SphinxQL or REST APIs +# rather than the native SphinxAPI. +# +# While both the native SphinxAPI protocol and the existing APIs will +# continue to exist, and perhaps should not even break (too much), exposing +# all the new features via multiple different native API implementations +# is too much of a support complication for us. +# +# That said, you're welcome to overtake the maintenance of any given +# official API, and remove this warning ;) +# + +from __future__ import print_function +import sys +import select +import socket +import re +from struct import * + +if sys.version_info > (3,): + long = int + text_type = str +else: + text_type = unicode + +# known searchd commands +SEARCHD_COMMAND_SEARCH = 0 +SEARCHD_COMMAND_EXCERPT = 1 +SEARCHD_COMMAND_UPDATE = 2 +SEARCHD_COMMAND_KEYWORDS = 3 +SEARCHD_COMMAND_PERSIST = 4 +SEARCHD_COMMAND_STATUS = 5 +SEARCHD_COMMAND_FLUSHATTRS = 7 + +# current client-side command implementation versions +VER_COMMAND_SEARCH = 0x120 +VER_COMMAND_EXCERPT = 0x104 +VER_COMMAND_UPDATE = 0x103 +VER_COMMAND_KEYWORDS = 0x100 +VER_COMMAND_STATUS = 0x101 +VER_COMMAND_FLUSHATTRS = 0x100 + +# known searchd status codes +SEARCHD_OK = 0 +SEARCHD_ERROR = 1 +SEARCHD_RETRY = 2 +SEARCHD_WARNING = 3 + +# known ranking modes (extended2 mode only) +SPH_RANK_PROXIMITY_BM15 = 0 # default mode, phrase proximity major factor and BM15 minor one +SPH_RANK_BM15 = 1 # statistical mode, BM15 ranking only (faster but worse quality) +SPH_RANK_NONE = 2 # no ranking, all matches get a weight of 1 +SPH_RANK_WORDCOUNT = 3 # simple word-count weighting, rank is a weighted sum of per-field keyword occurence counts +SPH_RANK_PROXIMITY = 4 +SPH_RANK_MATCHANY = 5 +SPH_RANK_FIELDMASK = 6 +SPH_RANK_SPH04 = 7 +SPH_RANK_EXPR = 8 +SPH_RANK_TOTAL = 9 + +# aliases; to be retired +SPH_RANK_PROXIMITY_BM25 = 0 +SPH_RANK_BM25 = 1 + +# known sort modes +SPH_SORT_RELEVANCE = 0 +SPH_SORT_ATTR_DESC = 1 +SPH_SORT_ATTR_ASC = 2 +SPH_SORT_TIME_SEGMENTS = 3 +SPH_SORT_EXTENDED = 4 + +# known filter types +SPH_FILTER_VALUES = 0 +SPH_FILTER_RANGE = 1 +SPH_FILTER_FLOATRANGE = 2 +SPH_FILTER_STRING = 3 +SPH_FILTER_STRING_LIST = 6 + +# known attribute types +SPH_ATTR_NONE = 0 +SPH_ATTR_INTEGER = 1 +SPH_ATTR_TIMESTAMP = 2 +SPH_ATTR_ORDINAL = 3 +SPH_ATTR_BOOL = 4 +SPH_ATTR_FLOAT = 5 +SPH_ATTR_BIGINT = 6 +SPH_ATTR_STRING = 7 +SPH_ATTR_FACTORS = 1001 +SPH_ATTR_MULTI = long(0X40000001) +SPH_ATTR_MULTI64 = long(0X40000002) + +SPH_ATTR_TYPES = (SPH_ATTR_NONE, + SPH_ATTR_INTEGER, + SPH_ATTR_TIMESTAMP, + SPH_ATTR_ORDINAL, + SPH_ATTR_BOOL, + SPH_ATTR_FLOAT, + SPH_ATTR_BIGINT, + SPH_ATTR_STRING, + SPH_ATTR_MULTI, + SPH_ATTR_MULTI64) + +# known grouping functions +SPH_GROUPBY_DAY = 0 +SPH_GROUPBY_WEEK = 1 +SPH_GROUPBY_MONTH = 2 +SPH_GROUPBY_YEAR = 3 +SPH_GROUPBY_ATTR = 4 +SPH_GROUPBY_ATTRPAIR = 5 + + +class SphinxClient: + def __init__ (self): + """ + Create a new client object, and fill defaults. + """ + self._host = 'localhost' # searchd host (default is "localhost") + self._port = 9312 # searchd port (default is 9312) + self._path = None # searchd unix-domain socket path + self._socket = None + self._offset = 0 # how much records to seek from result-set start (default is 0) + self._limit = 20 # how much records to return from result-set starting at offset (default is 20) + self._weights = [] # per-field weights (default is 1 for all fields) + self._sort = SPH_SORT_RELEVANCE # match sorting mode (default is SPH_SORT_RELEVANCE) + self._sortby = bytearray() # attribute to sort by (defualt is "") + self._min_id = 0 # min ID to match (default is 0) + self._max_id = 0 # max ID to match (default is UINT_MAX) + self._filters = [] # search filters + self._groupby = bytearray() # group-by attribute name + self._groupfunc = SPH_GROUPBY_DAY # group-by function (to pre-process group-by attribute value with) + self._groupsort = str_bytes('@group desc') # group-by sorting clause (to sort groups in result set with) + self._groupdistinct = bytearray() # group-by count-distinct attribute + self._maxmatches = 1000 # max matches to retrieve + self._cutoff = 0 # cutoff to stop searching at + self._retrycount = 0 # distributed retry count + self._retrydelay = 0 # distributed retry delay + self._indexweights = {} # per-index weights + self._ranker = SPH_RANK_PROXIMITY_BM15 # ranking mode + self._rankexpr = bytearray() # ranking expression for SPH_RANK_EXPR + self._maxquerytime = 0 # max query time, milliseconds (default is 0, do not limit) + self._timeout = 1.0 # connection timeout + self._fieldweights = {} # per-field-name weights + self._select = str_bytes('*') # select-list (attributes or expressions, with optional aliases) + self._query_flags = SetBit ( 0, 6, True ) # default idf=tfidf_normalized + self._predictedtime = 0 # per-query max_predicted_time + self._outerorderby = bytearray() # outer match sort by + self._outeroffset = 0 # outer offset + self._outerlimit = 0 # outer limit + self._hasouter = False # sub-select enabled + self._tokenfilterlibrary = bytearray() # token_filter plugin library name + self._tokenfiltername = bytearray() # token_filter plugin name + self._tokenfilteropts = bytearray() # token_filter plugin options + + self._error = '' # last error message + self._warning = '' # last warning message + self._reqs = [] # requests array for multi-query + + def __del__ (self): + if self._socket: + self._socket.close() + + + def GetLastError (self): + """ + Get last error message (string). + """ + return self._error + + + def GetLastWarning (self): + """ + Get last warning message (string). + """ + return self._warning + + + def SetServer (self, host, port = None): + """ + Set searchd server host and port. + """ + assert(isinstance(host, str)) + if host.startswith('/'): + self._path = host + return + elif host.startswith('unix://'): + self._path = host[7:] + return + self._host = host + if isinstance(port, int): + assert(port>0 and port<65536) + self._port = port + self._path = None + + def SetConnectTimeout ( self, timeout ): + """ + Set connection timeout ( float second ) + """ + assert (isinstance(timeout, float)) + # set timeout to 0 make connaection non-blocking that is wrong so timeout got clipped to reasonable minimum + self._timeout = max ( 0.001, timeout ) + + def _Connect (self): + """ + INTERNAL METHOD, DO NOT CALL. Connects to searchd server. + """ + if self._socket: + # we have a socket, but is it still alive? + sr, sw, _ = select.select ( [self._socket], [self._socket], [], 0 ) + + # this is how alive socket should look + if len(sr)==0 and len(sw)==1: + return self._socket + + # oops, looks like it was closed, lets reopen + self._socket.close() + self._socket = None + + try: + if self._path: + af = socket.AF_UNIX + addr = self._path + desc = self._path + else: + af = socket.AF_INET + addr = ( self._host, self._port ) + desc = '%s;%s' % addr + sock = socket.socket ( af, socket.SOCK_STREAM ) + sock.settimeout ( self._timeout ) + sock.connect ( addr ) + except socket.error as msg: + if sock: + sock.close() + self._error = 'connection to %s failed (%s)' % ( desc, msg ) + return + + v = unpack('>L', sock.recv(4))[0] + if v<1: + sock.close() + self._error = 'expected searchd protocol version, got %s' % v + return + + # all ok, send my version + sock.send(pack('>L', 1)) + return sock + + + def _GetResponse (self, sock, client_ver): + """ + INTERNAL METHOD, DO NOT CALL. Gets and checks response packet from searchd server. + """ + (status, ver, length) = unpack('>2HL', sock.recv(8)) + response = bytearray() + left = length + while left>0: + chunk = sock.recv(left) + if chunk: + response += chunk + left -= len(chunk) + else: + break + + if not self._socket: + sock.close() + + # check response + read = len(response) + if not response or read!=length: + if length: + self._error = 'failed to read searchd response (status=%s, ver=%s, len=%s, read=%s)' \ + % (status, ver, length, read) + else: + self._error = 'received zero-sized searchd response' + return None + + # check status + if status==SEARCHD_WARNING: + wend = 4 + unpack ( '>L', response[0:4] )[0] + self._warning = bytes_str(response[4:wend]) + return response[wend:] + + if status==SEARCHD_ERROR: + self._error = 'searchd error: ' + bytes_str(response[4:]) + return None + + if status==SEARCHD_RETRY: + self._error = 'temporary searchd error: ' + bytes_str(response[4:]) + return None + + if status!=SEARCHD_OK: + self._error = 'unknown status code %d' % status + return None + + # check version + if ver配置修改
运行日志
查询日志
+运行状态
重建索引
| 运行时间 | ' + idata.uptime + 's | 每秒查询 | ' + parseInt(parseInt(idata.queries) / parseInt(idata.uptime)) + ' |
|---|---|---|---|
| 总连接次数 | ' + idata.connections + ' | work_queue_length | ' +idata.work_queue_length + ' |
| agent_connect | ' + idata.agent_connect+ ' | workers_active | ' + idata.workers_active + ' |
| agent_retry | ' + idata.agent_retry + ' | workers_total | ' + idata.workers_total + ' |
| \ + \ + | |||
|---|---|---|---|
| command_delete | ' + idata.command_delete + ' | command_delete | |
| command_excerpt | ' + idata.command_excerpt + ' | command_excerpt | |
| command_flushattrs | ' + idata.command_flushattrs + ' | command_flushattrs | |
| command_keywords | ' + idata.command_keywords + ' | command_keywords | |
| command_persist | ' + idata.command_persist + ' | command_persist | |
| command_search | ' + idata.command_search + ' | command_search | |
| command_status | ' + idata.command_status + ' | command_status | |
| command_update | ' + idata.command_update + ' | command_update | |