From 7756a2edf3b5486a7cb5fe0fbd89887fccbd2f76 Mon Sep 17 00:00:00 2001 From: midoks Date: Tue, 26 Jul 2022 22:27:26 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BD=91=E7=AB=99=E7=BB=9F=E8=AE=A1=20x23=20IP?= =?UTF-8?q?,URI=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/webstats/index.html | 10 ++ plugins/webstats/index.py | 217 +++++++++++++++++++++++++++++++ plugins/webstats/info.json | 2 +- plugins/webstats/js/stats.js | 234 ++++++++++++++++++++++++++++++++++ plugins/webstats/lua/webstats_log.lua | 6 +- 5 files changed, 465 insertions(+), 4 deletions(-) diff --git a/plugins/webstats/index.html b/plugins/webstats/index.html index 0321675c8..b50464cb5 100755 --- a/plugins/webstats/index.html +++ b/plugins/webstats/index.html @@ -32,6 +32,14 @@ overflow: auto; } +.share_num { + background-color: #ff7e0e; + box-sizing: border-box; + height: 25px; + display: inline-block; + vertical-align: bottom; +} + .form-control{ border-radius: 0px; } @@ -187,6 +195,8 @@

网站列表

蜘蛛统计

客服端统计

+

IP统计

+

URI统计

错误日志

网站日志

全局设置

diff --git a/plugins/webstats/index.py b/plugins/webstats/index.py index 275efadc5..35fec34b1 100755 --- a/plugins/webstats/index.py +++ b/plugins/webstats/index.py @@ -862,6 +862,219 @@ def getClientStatList(): return mw.returnJson(True, 'ok', data) +def getDateRangeList(start, end): + dlist = [] + if start > end: + for x in list(range(start, 32, 1)): + dlist.append(x) + + for x in list(range(1, end, 1)): + dlist.append(x) + else: + for x in list(range(start, end, 1)): + dlist.append(x) + + return dlist + + +def getIpStatList(): + args = getArgs() + check = checkArgs(args, ['site', 'query_date']) + if not check[0]: + return check[1] + + domain = args['site'] + tojs = args['tojs'] + query_date = args['query_date'] + setDefaultSite(domain) + + conn = pSqliteDb('ip_stat', domain) + + origin_field = "ip,day,flow" + + if query_date == "today": + ftime = time.localtime(time.time()) + day = ftime.tm_mday + + field_day = "day" + str(day) + field_flow = "flow" + str(day) + # print(field_day, field_flow) + + field = "ip," + field_day + ' as day,' + field_flow + " as flow" + + conn = conn.field(field) + conn = conn.where("day>? and flow>?", (0, 0,)) + + elif query_date == "yesterday": + + ftime = time.localtime(time.time() - 86400) + day = ftime.tm_mday + + field_day = "day" + str(day) + field_flow = "flow" + str(day) + + field = "ip," + field_day + ' as day,' + field_flow + " as flow" + + conn = conn.field(field) + conn = conn.where("day>? and flow>?", (0, 0,)) + elif query_date == "l7": + + field_day = "" + field_flow = "" + + now_time = time.localtime(time.time()) + end_day = now_time.tm_mday + + start_time = time.localtime(time.time() - 7 * 86400) + start_day = start_time.tm_mday + + rlist = getDateRangeList(start_day, end_day) + + for x in rlist: + field_day += "+cast(day" + str(x) + " as TEXT)" + field_flow += "+cast(flow" + str(x) + " as TEXT)" + + field_day = field_day.strip("+") + field_flow = field_flow.strip("+") + + field = "ip,(" + field_day + ') as day,(' + field_flow + ") as flow" + conn = conn.field(field) + conn = conn.where("day>? and flow>?", (0, 0,)) + + elif query_date == "l30": + + field_day = "" + field_flow = "" + + for x in list(range(1, 32, 1)): + field_day += "+cast(day" + str(x) + " as TEXT)" + field_flow += "+cast(flow" + str(x) + " as TEXT)" + + field_day = field_day.strip("+") + field_flow = field_flow.strip("+") + + # print(field_day) + # print(field_flow) + field = "ip,(" + field_day + ') as day,(' + field_flow + ") as flow" + conn = conn.field(field) + conn = conn.where("day>? and flow>?", (0, 0,)) + + clist = conn.order("flow desc").limit("50").inquiry(origin_field) + # print(clist) + + total_req = 0 + total_flow = 0 + + for x in clist: + total_req += x['day'] + total_flow += x['flow'] + + for i in range(len(clist)): + clist[i]['day_rate'] = round((clist[i]['day'] / total_req) * 100, 2) + clist[i]['flow_rate'] = round((clist[i]['flow'] / total_flow) * 100, 2) + + return mw.returnJson(True, 'ok', clist) + + +def getUriStatList(): + args = getArgs() + check = checkArgs(args, ['site', 'query_date']) + if not check[0]: + return check[1] + + domain = args['site'] + tojs = args['tojs'] + query_date = args['query_date'] + setDefaultSite(domain) + + conn = pSqliteDb('uri_stat', domain) + + origin_field = "uri,day,flow" + + if query_date == "today": + ftime = time.localtime(time.time()) + day = ftime.tm_mday + + field_day = "day" + str(day) + field_flow = "flow" + str(day) + # print(field_day, field_flow) + + field = "uri," + field_day + ' as day,' + field_flow + " as flow" + + conn = conn.field(field) + conn = conn.where("day>? and flow>?", (0, 0,)) + + elif query_date == "yesterday": + + ftime = time.localtime(time.time() - 86400) + day = ftime.tm_mday + + field_day = "day" + str(day) + field_flow = "flow" + str(day) + + field = "uri," + field_day + ' as day,' + field_flow + " as flow" + + conn = conn.field(field) + conn = conn.where("day>? and flow>?", (0, 0,)) + elif query_date == "l7": + + field_day = "" + field_flow = "" + + now_time = time.localtime(time.time()) + end_day = now_time.tm_mday + + start_time = time.localtime(time.time() - 7 * 86400) + start_day = start_time.tm_mday + + rlist = getDateRangeList(start_day, end_day) + + for x in rlist: + field_day += "+cast(day" + str(x) + " as TEXT)" + field_flow += "+cast(flow" + str(x) + " as TEXT)" + + field_day = field_day.strip("+") + field_flow = field_flow.strip("+") + + field = "uri,(" + field_day + ') as day,(' + field_flow + ") as flow" + conn = conn.field(field) + conn = conn.where("day>? and flow>?", (0, 0,)) + + elif query_date == "l30": + + field_day = "" + field_flow = "" + + for x in list(range(1, 32, 1)): + field_day += "+cast(day" + str(x) + " as TEXT)" + field_flow += "+cast(flow" + str(x) + " as TEXT)" + + field_day = field_day.strip("+") + field_flow = field_flow.strip("+") + + # print(field_day) + # print(field_flow) + field = "uri,(" + field_day + ') as day,(' + field_flow + ") as flow" + conn = conn.field(field) + conn = conn.where("day>? and flow>?", (0, 0,)) + + clist = conn.order("flow desc").limit("50").inquiry(origin_field) + # print(clist) + + total_req = 0 + total_flow = 0 + + for x in clist: + total_req += x['day'] + total_flow += x['flow'] + + for i in range(len(clist)): + clist[i]['day_rate'] = round((clist[i]['day'] / total_req) * 100, 2) + clist[i]['flow_rate'] = round((clist[i]['flow'] / total_flow) * 100, 2) + + return mw.returnJson(True, 'ok', clist) + + def getWebLogCount(domain, query_date): conn = pSqliteDb('web_logs', domain) @@ -1022,6 +1235,10 @@ if __name__ == "__main__": print(getLogsRealtimeInfo()) elif func == 'get_client_stat_list': print(getClientStatList()) + elif func == 'get_ip_stat_list': + print(getIpStatList()) + elif func == 'get_uri_stat_list': + print(getUriStatList()) elif func == 'get_spider_stat_list': print(getSpiderStatList()) else: diff --git a/plugins/webstats/info.json b/plugins/webstats/info.json index 0958d5c3a..f404a37d5 100755 --- a/plugins/webstats/info.json +++ b/plugins/webstats/info.json @@ -4,7 +4,7 @@ "name": "webstats", "title": "网站统计", "shell": "install.sh", - "versions":["0.1.0"], + "versions":["0.2.0"], "tip": "soft", "checks": "server/webstats", "path": "server/webstats", diff --git a/plugins/webstats/js/stats.js b/plugins/webstats/js/stats.js index 3b5b5a98d..88240c96a 100644 --- a/plugins/webstats/js/stats.js +++ b/plugins/webstats/js/stats.js @@ -1731,6 +1731,240 @@ wsPost('get_default_site','',{},function(rdata){ +function wsIpStatLogRequest(page){ + + var args = {} + args['site'] = $('select[name="site"]').val(); + var query_date = 'today'; + query_date = $('#search_time button.cur').attr("data-name"); + args['query_date'] = query_date; + + args['tojs'] = 'wsIpStatLogRequest'; + wsPost('get_ip_stat_list', '' ,args, function(rdata){ + var rdata = $.parseJSON(rdata.data); + var list = ''; + var data = rdata.data; + // console.log(rdata,data); + if (data.length > 0){ + for(i in data){ + list += ''; + list += '' + (parseInt(i)+1)+''; + list += '' + data[i]['ip']+''; + list += '' + "0" +''; + list += '' + data[i]['day'] +'('+data[i]['day_rate']+'%)'; + list += '' + toSize(data[i]['flow']) +'('+data[i]['flow_rate']+'%)'; + list += '' +''; + list += ''; + } + + + } else{ + list += 'IP列表为空'; + } + + var table = '
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + '+ list +'\ +
序号IP归属地(仅供参考)请求数流量流量占比图
\ +
\ +
'; + $('#ws_table').html(table); + }); +} + + +function wsIpStat(){ +//////////////////////////////////////////////////////////////////////////////////////////////////////// +var randstr = getRandomString(10); + +var html = '
\ +
\ + 网站: \ + \ + 时间: \ +
\ +
\ + \ + \ + \ + \ +
\ +
\ +
\ +
\ +
'; +$(".soft-man-con").html(html); + + +$('#search_time button:eq(0)').addClass('cur'); +$('#search_time button').click(function(){ + $('#search_time button').each(function(){ + if ($(this).hasClass('cur')){ + $(this).removeClass('cur'); + } + }); + $('#time_choose').attr("data-name",''); + $('#time_choose').removeClass("cur"); + + $(this).addClass('cur'); + + wsIpStatLogRequest(1); +}); + +wsPost('get_default_site','',{},function(rdata){ + $('select[name="site"]').html(''); + + var rdata = $.parseJSON(rdata.data); + var rdata = rdata.data; + var default_site = rdata["default"]; + var select = ''; + for (var i = 0; i < rdata["list"].length; i++) { + if (default_site == rdata["list"][i]){ + select += ''; + } else{ + select += ''; + } + } + $('select[name="site"]').html(select); + wsIpStatLogRequest(1); + + $('select[name="site"]').change(function(){ + wsIpStatLogRequest(1); + }); +}); + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +} + + +function wsUriStatLogRequest(page){ + + var args = {} + args['site'] = $('select[name="site"]').val(); + var query_date = 'today'; + query_date = $('#search_time button.cur').attr("data-name"); + args['query_date'] = query_date; + + args['tojs'] = 'wsUriStatLogRequest'; + wsPost('get_uri_stat_list', '' ,args, function(rdata){ + var rdata = $.parseJSON(rdata.data); + var list = ''; + var data = rdata.data; + // console.log(rdata,data); + if (data.length > 0){ + for(i in data){ + list += ''; + list += '' + (parseInt(i)+1)+''; + list += '' + data[i]['uri']+''; + list += '' + data[i]['day'] +'('+data[i]['day_rate']+'%)'; + list += '' + toSize(data[i]['flow']) +'('+data[i]['flow_rate']+'%)'; + list += '' +''; + list += ''; + } + + + } else{ + list += 'URI列表为空'; + } + + var table = '
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + '+ list +'\ +
序号URI请求数流量流量占比图
\ +
\ +
'; + $('#ws_table').html(table); + }); +} + + +function wsUriStat(){ +//////////////////////////////////////////////////////////////////////////////////////////////////////// +var randstr = getRandomString(10); + +var html = '
\ +
\ + 网站: \ + \ + 时间: \ +
\ +
\ + \ + \ + \ + \ +
\ +
\ +
\ +
\ +
'; +$(".soft-man-con").html(html); + + +$('#search_time button:eq(0)').addClass('cur'); +$('#search_time button').click(function(){ + $('#search_time button').each(function(){ + if ($(this).hasClass('cur')){ + $(this).removeClass('cur'); + } + }); + $('#time_choose').attr("data-name",''); + $('#time_choose').removeClass("cur"); + + $(this).addClass('cur'); + + wsUriStatLogRequest(1); +}); + +wsPost('get_default_site','',{},function(rdata){ + $('select[name="site"]').html(''); + + var rdata = $.parseJSON(rdata.data); + var rdata = rdata.data; + var default_site = rdata["default"]; + var select = ''; + for (var i = 0; i < rdata["list"].length; i++) { + if (default_site == rdata["list"][i]){ + select += ''; + } else{ + select += ''; + } + } + $('select[name="site"]').html(select); + wsUriStatLogRequest(1); + + $('select[name="site"]').change(function(){ + wsUriStatLogRequest(1); + }); +}); + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +} + + + + function wsTableErrorLogRequest(page){ diff --git a/plugins/webstats/lua/webstats_log.lua b/plugins/webstats/lua/webstats_log.lua index 84ea6d69f..89e689fe9 100644 --- a/plugins/webstats/lua/webstats_log.lua +++ b/plugins/webstats/lua/webstats_log.lua @@ -4,7 +4,7 @@ log_by_lua_block { -- -- - local ver = '0.0.1' + local ver = '0.2.0' local max_log_id = 99999999999999 local debug_mode = true @@ -560,7 +560,7 @@ log_by_lua_block { if site_exclude_ip then for i, _ip in pairs(site_exclude_ip) do - D("set exclude ip: ".._ip) + -- D("set exclude ip: ".._ip) cache:set(input_server_name .. "_exclude_ip_".._ip, true) end end @@ -903,7 +903,7 @@ log_by_lua_block { local worker_id = ngx.worker.id() if is_working(input_server_name) then - -- D("其他worker正在存储中,稍候存储。") + -- D("other workers are being stored, please store later.") -- cache:delete(flush_data_key) return true end