pull/216/head
midoks 3 years ago
parent f3e7dd1cc0
commit 011949ba85
  1. 10
      plugins/op_waf/waf/lua/common.lua
  2. 9
      plugins/op_waf/waf/lua/init.lua
  3. 23
      plugins/webstats/index.py
  4. 2
      plugins/webstats/info.json
  5. 20
      plugins/webstats/install.sh
  6. 384
      plugins/webstats/lua/webstats_common.lua
  7. 114
      plugins/webstats/lua/webstats_log.lua
  8. 24
      plugins/webstats/t/bench/bench.sh
  9. 18
      plugins/webstats/t/bench/simple.lua
  10. 33
      plugins/webstats/t/bench/test_today.lua
  11. 95
      plugins/webstats/t/index.py
  12. 6
      plugins/webstats/t/test.sh

@ -30,6 +30,8 @@ function _M.new(self)
end end
function _M.getInstance(self) function _M.getInstance(self)
if rawget(self, "instance") == nil then if rawget(self, "instance") == nil then
rawset(self, "instance", self.new()) rawset(self, "instance", self.new())
@ -258,6 +260,14 @@ function _M.write_to_file(self, logstr)
return true return true
end end
-- 是否文件迁入数据库中
function _M.is_migrating(self)
local migrating = self.waf_root +"/migrating"
local file = io.open(migrating, "rb")
if file then return true end
return false
end
function _M.continue_key(self,key) function _M.continue_key(self,key)
key = tostring(key) key = tostring(key)

@ -4,8 +4,6 @@ local ngx_match = ngx.re.find
local __C = require "common" local __C = require "common"
local C = __C:getInstance() local C = __C:getInstance()
local waf_root = "{$WAF_ROOT}"
local config = require "config" local config = require "config"
local site_config = require "site" local site_config = require "site"
local config_domains = require "domains" local config_domains = require "domains"
@ -13,9 +11,6 @@ local config_domains = require "domains"
C:setConfData(config, site_config) C:setConfData(config, site_config)
C:setDebug(true) C:setDebug(true)
-- local ngx_os = require "os"
-- C:("msss".. ngx_os.name)
local get_html = require "html_get" local get_html = require "html_get"
local post_html = require "html_post" local post_html = require "html_post"
@ -335,9 +330,9 @@ end
local function waf_url() local function waf_url()
if not config['get']['open'] or not C:is_site_config('get') then return false end if not config['get']['open'] or not C:is_site_config('get') then return false end
--正则-- --正则--
if C:is_ngx_match(url_rules,params["uri"],'url') then if C:is_ngx_match(url_rules, params["uri"], 'url') then
C:write_log('url','regular') C:write_log('url','regular')
C:return_html(config['get']['status'],get_html) C:return_html(config['get']['status'], get_html)
return true return true
end end
return false return false

@ -77,11 +77,11 @@ def status():
return 'start' return 'start'
def loadLuaLogFile(): def loadLuaFile(name):
lua_dir = getServerDir() + "/lua" lua_dir = getServerDir() + "/lua"
lua_dst = lua_dir + "/webstats_log.lua" lua_dst = lua_dir + "/" + name
lua_tpl = getPluginDir() + '/lua/webstats_log.lua' lua_tpl = getPluginDir() + '/lua/' + name
content = mw.readFile(lua_tpl) content = mw.readFile(lua_tpl)
content = content.replace('{$SERVER_APP}', getServerDir()) content = content.replace('{$SERVER_APP}', getServerDir())
content = content.replace('{$ROOT_PATH}', mw.getServerDir()) content = content.replace('{$ROOT_PATH}', mw.getServerDir())
@ -98,7 +98,7 @@ def loadConfigFile():
dst_conf_json = getServerDir() + "/lua/config.json" dst_conf_json = getServerDir() + "/lua/config.json"
mw.writeFile(dst_conf_json, json.dumps(content)) mw.writeFile(dst_conf_json, json.dumps(content))
dst_conf_lua = getServerDir() + "/lua/config.lua" dst_conf_lua = getServerDir() + "/lua/webstats_config.lua"
listToLuaFile(dst_conf_lua, content) listToLuaFile(dst_conf_lua, content)
@ -127,7 +127,7 @@ def loadLuaSiteFile():
ddata["default"] = dlist[0] ddata["default"] = dlist[0]
mw.writeFile(default_json, json.dumps(ddata)) mw.writeFile(default_json, json.dumps(ddata))
lua_site = lua_dir + "/sites.lua" lua_site = lua_dir + "/webstats_sites.lua"
listToLuaFile(lua_site, content) listToLuaFile(lua_site, content)
@ -205,7 +205,14 @@ def initDreplace():
if not os.path.exists(log_path): if not os.path.exists(log_path):
mw.execShell('mkdir -p ' + log_path) mw.execShell('mkdir -p ' + log_path)
loadLuaLogFile() file_list = [
'webstats_common.lua',
'webstats_log.lua',
]
for fl in file_list:
loadLuaFile(fl)
loadConfigFile() loadConfigFile()
loadLuaSiteFile() loadLuaSiteFile()
loadDebugLogFile() loadDebugLogFile()
@ -294,7 +301,7 @@ def setGlobalConf():
content['global']['exclude_url'] = exclude_url_val content['global']['exclude_url'] = exclude_url_val
mw.writeFile(conf, json.dumps(content)) mw.writeFile(conf, json.dumps(content))
conf_lua = getServerDir() + "/lua/config.lua" conf_lua = getServerDir() + "/lua/webstats_config.lua"
listToLuaFile(conf_lua, content) listToLuaFile(conf_lua, content)
mw.restartWeb() mw.restartWeb()
return mw.returnJson(True, '设置成功') return mw.returnJson(True, '设置成功')
@ -387,7 +394,7 @@ def setSiteConf():
content[domain] = site_conf content[domain] = site_conf
mw.writeFile(conf, json.dumps(content)) mw.writeFile(conf, json.dumps(content))
conf_lua = getServerDir() + "/lua/config.lua" conf_lua = getServerDir() + "/lua/webstats_config.lua"
listToLuaFile(conf_lua, content) listToLuaFile(conf_lua, content)
mw.restartWeb() mw.restartWeb()
return mw.returnJson(True, '设置成功') return mw.returnJson(True, '设置成功')

@ -4,7 +4,7 @@
"name": "webstats", "name": "webstats",
"title": "网站统计", "title": "网站统计",
"shell": "install.sh", "shell": "install.sh",
"versions":["0.2.0"], "versions":["0.2.2"],
"tip": "soft", "tip": "soft",
"install_pre_inspection":true, "install_pre_inspection":true,
"checks": "server/webstats", "checks": "server/webstats",

@ -28,8 +28,6 @@ Install_App()
{ {
echo '正在安装脚本文件...' > $install_tmp echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source/webstats mkdir -p $serverPath/source/webstats
mkdir -p $serverPath/webstats mkdir -p $serverPath/webstats
# 下载源码安装包 # 下载源码安装包
@ -87,19 +85,25 @@ Install_App()
fi fi
# https://github.com/P3TERX/GeoLite.mmdb # https://github.com/P3TERX/GeoLite.mmdb
pip install geoip2 # pip install geoip2
if [ ! -f $serverPath/webstats/GeoLite2-City.mmdb ];then # if [ ! -f $serverPath/webstats/GeoLite2-City.mmdb ];then
wget --no-check-certificate -O $serverPath/webstats/GeoLite2-City.mmdb https://git.io/GeoLite2-City.mmdb # wget --no-check-certificate -O $serverPath/webstats/GeoLite2-City.mmdb https://github.com/P3TERX/GeoLite.mmdb/releases/download/2022.10.16/GeoLite2-City.mmdb
# fi
# 缓存数据
if [ ! -f $serverPath/source/webstats/GeoLite2-City.mmdb ];then
wget --no-check-certificate -O $serverPath/source/webstats/GeoLite2-City.mmdb https://github.com/P3TERX/GeoLite.mmdb/releases/download/2022.10.16/GeoLite2-City.mmdb
fi fi
# GeoLite2-Country.mmdb if [ -f $serverPath/source/webstats/GeoLite2-City.mmdb ];then
cp -rf $serverPath/source/webstats/GeoLite2-City.mmdb $serverPath/webstats/GeoLite2-City.mmdb
fi
echo "${VERSION}" > $serverPath/webstats/version.pl echo "${VERSION}" > $serverPath/webstats/version.pl
echo '安装完成' > $install_tmp echo '安装完成' > $install_tmp
if [ "$sys_os" != "Darwin" ];then
cd $rootPath && python3 ${rootPath}/plugins/webstats/index.py start cd $rootPath && python3 ${rootPath}/plugins/webstats/index.py start
fi
} }
Uninstall_App() Uninstall_App()

@ -0,0 +1,384 @@
local setmetatable = setmetatable
local _M = { _VERSION = '1.0' }
local mt = { __index = _M }
local json = require "cjson"
local sqlite3 = require "lsqlite3"
local config = require "webstats_config"
local sites = require "webstats_sites"
local debug_mode = true
local total_key = "log_kv_total"
local cache = ngx.shared.mw_total
local today = ngx.re.gsub(ngx.today(),'-','')
local day = os.date("%d")
local number_day = tonumber(day)
local day_column = "day"..number_day
local flow_column = "flow"..number_day
local spider_column = "spider_flow"..number_day
function _M.new(self)
local self = {
total_key = total_key,
params = nil,
site_config = nil,
config = nil,
}
-- self.dbs = {}
return setmetatable(self, mt)
end
function _M.getInstance(self)
if rawget(self, "instance") == nil then
rawset(self, "instance", self.new())
self:cron()
end
assert(self.instance ~= nil)
return self.instance
end
function _M.initDB(self, input_sn)
local log_dir = "{$SERVER_APP}/logs"
local path = log_dir .. '/' .. input_sn .. "/logs.db"
db, _ = sqlite3.open(path)
return db
end
function _M.getTotalKey(self)
return self.total_key
end
function _M.setConfData( self, config, site_config )
self.config = config
self.site_config = site_config
end
function _M.setParams( self, params )
self.params = params
end
function _M.split(self, str, reps)
local arr = {}
string.gsub(str,'[^'..reps..']+',function(w) table.insert(arr,w) end)
return arr
end
-- 后台任务
function _M.cron(self)
local timer_every_get_data = function (premature)
local llen, _ = ngx.shared.mw_total:llen(total_key)
-- self:D("cron llen:"..tostring(llen))
for i=1,llen do
local data, _ = ngx.shared.mw_total:lpop(total_key)
if data then
local info = json.decode(data)
self:store_logs(info)
end
end
-- local capacity_bytes = ngx.shared.mw_total:free_space()
-- self:D("cron free_capacity:"..tostring(capacity_bytes))
end
ngx.timer.every(1, timer_every_get_data)
end
function _M.store_logs_line(self, db, stmt, input_sn, info)
local logline = info['log_kv']
local time = logline["time"]
local id = logline["id"]
local protocol = logline["protocol"]
local client_port = logline["client_port"]
local status_code = logline["status_code"]
local uri = logline["uri"]
local request_uri = logline["request_uri"]
local method = logline["method"]
local body_length = logline["body_length"]
local referer = logline["referer"]
local ip = logline["ip"]
local ip_list = logline["ip_list"]
local request_time = logline["request_time"]
local is_spider = logline["is_spider"]
local domain = logline["domain"]
local server_name = logline["server_name"]
local user_agent = logline["user_agent"]
local request_headers = logline["request_headers"]
local excluded = logline["excluded"]
local request_stat_fields = nil
local client_stat_fields = nil
local spider_stat_fields = nil
local stat_fields = info['stat_fields']
if stat_fields == nil then
-- D("Log stat fields is nil.")
-- D("Logdata:"..logvalue)
else
stat_fields = self:split(stat_fields, ";")
request_stat_fields = stat_fields[1]
client_stat_fields = stat_fields[2]
spider_stat_fields = stat_fields[3]
if "x" == client_stat_fields then
client_stat_fields = nil
end
if "x" == spider_stat_fields then
spider_stat_fields = nil
end
end
local time_key = logline["time_key"]
if not excluded then
stmt:bind_names {
time=time,
ip=ip,
domain=domain,
server_name=server_name,
method=method,
status_code=status_code,
uri=request_uri,
body_length=body_length,
referer=referer,
user_agent=user_agent,
protocol=protocol,
request_time=request_time,
is_spider=is_spider,
request_headers=request_headers,
ip_list=ip_list,
client_port=client_port,
}
local res, err = stmt:step()
if tostring(res) == "5" then
self:D("step res:"..tostring(res))
self:D("step err:"..tostring(err))
self:D("the step database connection is busy, so it will be stored later.")
return false
end
stmt:reset()
self:update_stat( db, "client_stat", time_key, client_stat_fields)
self:update_stat( db, "spider_stat", time_key, spider_stat_fields)
-- self:D("stat ok")
-- only count non spider requests
local ok, err = self:statistics_uri(db, request_uri, ngx.md5(request_uri), body_length)
local ok, err = self:statistics_ip(db, ip, body_length)
-- self:D("stat url ip ok")
end
self:update_stat( db, "request_stat", time_key, request_stat_fields)
return true
end
function _M.statistics_uri(self, db, uri, uri_md5, body_length)
-- count the number of URI requests and traffic
local open_statistics_uri = config['global']["statistics_uri"]
if not open_statistics_uri then return true end
local stat_sql = nil
stat_sql = "INSERT INTO uri_stat(uri_md5,uri) SELECT \""..uri_md5.."\",\""..uri.."\" WHERE NOT EXISTS (SELECT uri_md5 FROM uri_stat WHERE uri_md5=\""..uri_md5.."\");"
local res, err = db:exec(stat_sql)
stat_sql = "UPDATE uri_stat SET "..day_column.."="..day_column.."+1,"..flow_column.."="..flow_column.."+"..body_length.." WHERE uri_md5=\""..uri_md5.."\""
local res, err = db:exec(stat_sql)
return true
end
function _M.statistics_ip(self, db, ip, body_length)
local open_statistics_ip = config['global']["statistics_ip"]
if not open_statistics_ip then return true end
local stat_sql = nil
stat_sql = "INSERT INTO ip_stat(ip) SELECT \""..ip.."\" WHERE NOT EXISTS (SELECT ip FROM ip_stat WHERE ip=\""..ip.."\");"
local res, err = db:exec(stat_sql)
stat_sql = "UPDATE ip_stat SET "..day_column.."="..day_column.."+1,"..flow_column.."="..flow_column.."+"..body_length.." WHERE ip=\""..ip.."\""
local res, err = db:exec(stat_sql)
return true
end
function _M.update_stat(self,db, stat_table, key, columns)
-- 根据指定表名,更新统计数据
if not columns then return end
local stmt = db:prepare(string.format("INSERT INTO %s(time) SELECT :time WHERE NOT EXISTS(SELECT time FROM %s WHERE time=:time);", stat_table, stat_table))
stmt:bind_names{time=key}
local res, err = stmt:step()
stmt:finalize()
local update_sql = "UPDATE ".. stat_table .. " SET " .. columns
update_sql = update_sql .. " WHERE time=" .. key
status, errorString = db:exec(update_sql)
end
function _M.store_logs(self,info)
local input_sn = info["server_name"]
-- 迁移合并时不执行
if self:is_migrating(input_sn) == true then
return
end
if self:is_working(input_sn) then
return true
end
self:lock_working(input_sn)
local db = self:initDB(input_sn)
local stmt2 = nil
if db ~= nil then
stmt2 = db:prepare[[INSERT INTO web_logs(
time, ip, domain, server_name, method, status_code, uri, body_length,
referer, user_agent, protocol, request_time, is_spider, request_headers, ip_list, client_port)
VALUES(:time, :ip, :domain, :server_name, :method, :status_code, :uri,
:body_length, :referer, :user_agent, :protocol, :request_time, :is_spider,
:request_headers, :ip_list, :client_port)]]
end
if db == nil or stmt2 == nil then
if db and db:isopen() then
db:close()
end
return true
end
db:exec([[PRAGMA synchronous = 0]])
db:exec([[PRAGMA page_size = 4096]])
db:exec([[PRAGMA journal_mode = wal]])
db:exec([[PRAGMA journal_size_limit = 1073741824]])
status, errorString = db:exec([[BEGIN TRANSACTION]])
local update_day = self:load_update_day(input_sn)
if not update_day or update_day ~= today then
local update_sql = "UPDATE uri_stat SET "..day_column.."=0,"..flow_column.."=0"
status, errorString = db:exec(update_sql)
update_sql = "UPDATE ip_stat SET "..day_column.."=0,"..flow_column.."=0"
status, errorString = db:exec(update_sql)
self:write_update_day(input_sn)
end
self:store_logs_line(db, stmt2, input_sn, info)
local res, err = stmt2:finalize()
if tostring(res) == "5" then
-- self:D("Finalize res:"..tostring(res))
-- self:D("Finalize err:"..tostring(err))
end
local now_date = os.date("*t")
local save_day = config['global']["save_day"]
local save_date_timestamp = os.time{year=now_date.year,
month=now_date.month, day=now_date.day-save_day, hour=0}
-- delete expire data
db:exec("DELETE FROM web_logs WHERE time<"..tostring(save_date_timestamp))
local res, err = db:execute([[COMMIT]])
if db and db:isopen() then
db:close()
end
self:unlock_working(input_sn)
end
-- debug func
function _M.D(self,msg)
if not debug_mode then return true end
local fp = io.open('{$SERVER_APP}/debug.log', 'ab')
if fp == nil then
return nil
end
local localtime = os.date("%Y-%m-%d %H:%M:%S")
if server_name then
fp:write(tostring(msg) .. "\n")
else
fp:write(localtime..":"..tostring(msg) .. "\n")
end
fp:flush()
fp:close()
return true
end
function _M.is_migrating(self,input_sn)
local file = io.open("{$SERVER_APP}/migrating", "rb")
if file then return true end
local file = io.open("{$SERVER_APP}/logs/"..input_sn.."/migrating", "rb")
if file then return true end
return false
end
function _M.is_working(self,input_sn)
local work_status = cache:get(input_sn.."_working")
if work_status ~= nil and work_status == true then
return true
end
return false
end
function _M.lock_working(self, input_sn)
local working_key = input_sn.."_working"
cache:set(working_key, true, 60)
end
function _M.unlock_working(self, input_sn)
local working_key = input_sn.."_working"
cache:set(working_key, false)
end
function _M.write_file(self, filename, body, mode)
local fp = io.open(filename, mode)
if fp == nil then
return nil
end
fp:write(body)
fp:flush()
fp:close()
return true
end
function _M.read_file_body(self, filename)
local fp = io.open(filename,'rb')
if not fp then
return nil
end
fbody = fp:read("*a")
fp:close()
if fbody == '' then
return nil
end
return fbody
end
function _M.load_update_day(self, input_sn)
local _file = "{$SERVER_APP}/logs/"..input_sn.."/update_day.log"
return self:read_file_body(_file)
end
function _M.write_update_day(self, input_sn)
local _file = "{$SERVER_APP}/logs/"..input_sn.."/update_day.log"
return self:write_file(_file, today, "w")
end
function _M.lpop(self)
local cache = ngx.shared.mw_total
return cache:lpop(total_key)
end
function _M.rpop(self)
local cache = ngx.shared.mw_total
return cache:rpop(total_key)
end
return _M

@ -1,16 +1,5 @@
log_by_lua_block { log_by_lua_block {
-- python3 ./plugins/webstats/index.py reload && ab -c 10 -n 1000 http://t1.cn/
--
--
local ver = '0.2.0'
local max_log_id = 99999999999999
local debug_mode = true
local unset_server_name = "unset"
local cpath = "{$SERVER_APP}/lua/" local cpath = "{$SERVER_APP}/lua/"
if not package.cpath:find(cpath) then if not package.cpath:find(cpath) then
package.cpath = cpath .. "?.so;" .. package.cpath package.cpath = cpath .. "?.so;" .. package.cpath
@ -19,24 +8,14 @@ log_by_lua_block {
package.path = cpath .. "?.lua;" .. package.path package.path = cpath .. "?.lua;" .. package.path
end end
-- debug func local ver = '0.2.0'
local function D(msg) local max_log_id = 99999999999999
if not debug_mode then return true end local debug_mode = true
local fp = io.open('{$SERVER_APP}/debug.log', 'ab')
if fp == nil then local unset_server_name = "unset"
return nil
end
local localtime = os.date("%Y-%m-%d %H:%M:%S")
if server_name then
fp:write(tostring(msg) .. "\n")
else
fp:write(localtime..":"..tostring(msg) .. "\n")
end
fp:flush()
fp:close()
return true
end
local __C = require "webstats_common"
local C = __C:getInstance()
-- cache start --- -- cache start ---
@ -56,17 +35,23 @@ log_by_lua_block {
local value = cache:get(line_kv) local value = cache:get(line_kv)
return value return value
end end
-- cache end --- -- cache end ---
-- domain config is import -- domain config is import
local db = nil local db = nil
local json = require "cjson" local json = require "cjson"
local sqlite3 = require "lsqlite3" local sqlite3 = require "lsqlite3"
local config = require "webstats_config"
local sites = require "webstats_sites"
C:setConfData(config, sites)
local server_name local server_name
local request_header local request_header
local method local method
local config
local auto_config local auto_config
local excluded local excluded
@ -78,14 +63,19 @@ log_by_lua_block {
local spider_column local spider_column
--- default common var end --- --- default common var end ---
local function to_json(msg)
return json.encode(msg)
end
local function init_var() local function init_var()
config = require "config"
request_header = ngx.req.get_headers() request_header = ngx.req.get_headers()
method = ngx.req.get_method() method = ngx.req.get_method()
day = os.date("%d") day = os.date("%d")
today = os.date("%Y%m%d") -- today = os.date("%Y%m%d")
today = ngx.re.gsub(ngx.today(),'-','')
number_day = tonumber(day) number_day = tonumber(day)
day_column = "day"..number_day day_column = "day"..number_day
@ -204,16 +194,21 @@ log_by_lua_block {
end end
end end
end end
-- ipv6
if type(client_ip) == 'table' then client_ip = "" end if type(client_ip) == 'table' then client_ip = "" end
if client_ip ~= "unknown" and string.match(client_ip,"^[%w:]+$") then if client_ip ~= "unknown" and ngx.re.match(client_ip,"^([a-fA-F0-9]*):") then
return client_ip return client_ip
end end
if string.match(client_ip,"%d+%.%d+%.%d+%.%d+") == nil or not is_ipaddr_bylog(client_ip) then
-- ipv4
if not ngx.re.match(client_ip,"\\d+\\.\\d+\\.\\d+\\.\\d+") == nil or not is_ipaddr_bylog(client_ip) then
client_ip = ngx.var.remote_addr client_ip = ngx.var.remote_addr
if client_ip == nil then if client_ip == nil then
client_ip = "unknown" client_ip = "unknown"
end end
end end
return client_ip return client_ip
end end
@ -292,26 +287,20 @@ log_by_lua_block {
end end
local function get_server_name(c_name) local function get_server_name(c_name)
local my_name = cache:get(c_name) local my_name = cache:get(c_name)
if my_name then return my_name end if my_name then return my_name end
-- D("get_server_name start")
local determined_name = nil local determined_name = nil
local sites = require "sites"
-- D("get_server_name"..json.encode(sites))
for _,v in ipairs(sites) for _,v in ipairs(sites)
do do
if c_name == v["name"] then if c_name == v["name"] then
cache:set(c_name, v['name'],3600) cache:set(c_name, v['name'],86400)
return v["name"] return v["name"]
end end
for _,d_name in ipairs(v['domains']) for _,d_name in ipairs(v['domains'])
do do
if c_name == d_name then if c_name == d_name then
cache:set(c_name,v['name'],3600) cache:set(c_name, v['name'], 86400)
return v['name'] return v['name']
elseif string.find(d_name, "*") then elseif string.find(d_name, "*") then
new_domain = string.gsub(d_name, '*', '.*') new_domain = string.gsub(d_name, '*', '.*')
@ -322,12 +311,11 @@ log_by_lua_block {
end end
end end
-- D("get_server_name end")
if determined_name then if determined_name then
cache:set(c_name, determined_name,3600) cache:set(c_name, determined_name,86400)
return determined_name return determined_name
end end
cache:set(c_name, unset_server_name, 3600) cache:set(c_name, unset_server_name, 86400)
return unset_server_name return unset_server_name
end end
@ -543,7 +531,7 @@ log_by_lua_block {
local ip_token = input_server_name..'_'..ip local ip_token = input_server_name..'_'..ip
if not cache:get(ip_token) then if not cache:get(ip_token) then
ipc = 1 ipc = 1
cache:set(ip_token,1,get_end_time()) cache:set(ip_token,1, get_end_time())
end end
return ipc return ipc
end end
@ -569,7 +557,7 @@ log_by_lua_block {
local uv_token = ngx.md5(ip .. request_header['user-agent'] .. today) local uv_token = ngx.md5(ip .. request_header['user-agent'] .. today)
if not cache:get(uv_token) then if not cache:get(uv_token) then
uvc = 1 uvc = 1
cache:set(uv_token,1,get_end_time()) cache:set(uv_token,1, get_end_time())
end end
end end
end end
@ -762,7 +750,7 @@ log_by_lua_block {
local domain = get_domain() local domain = get_domain()
local referer = ngx.var.http_referer local referer = ngx.var.http_referer
kv = { local kv = {
id=new_id, id=new_id,
time_key=time_key, time_key=time_key,
time=os.time(), time=os.time(),
@ -792,21 +780,19 @@ log_by_lua_block {
if not excluded then if not excluded then
if status_code == 500 or (method=="POST" and config["record_post_args"]==true) or (status_code==403 and config["record_get_403_args"]==true) then if status_code == 500 or (method=="POST" and config["record_post_args"] == true) or (status_code==403 and config["record_get_403_args"]==true) then
local data = "" local data = ""
local ok, err = pcall(function() data=get_http_original() end) local ok, err = pcall(function() data=get_http_original() end)
if ok and not err then if ok and not err then
kv["request_headers"] = data kv["request_headers"] = data
end end
-- D("Get http orgininal ok:"..tostring(ok))
-- D("Get http orgininal res:"..tostring(data))
end end
if ngx.re.find("500,501,502,503,504,505,506,507,509,510,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,421,422,423,424,425,426,449,451", tostring(status_code), "jo") then if ngx.re.find("500,501,502,503,504,505,506,507,509,510,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,421,422,423,424,425,426,449,451", tostring(status_code), "jo") then
local field = "status_"..status_code local field = "status_"..status_code
request_stat_fields = request_stat_fields .. ","..field.."="..field.."+1" request_stat_fields = request_stat_fields .. ","..field.."="..field.."+1"
end end
-- D("method:"..method) -- D("method:"..method)
local lower_method = string.lower(method) local lower_method = string.lower(method)
if ngx.re.find("get,post,put,patch,delete", lower_method, "ijo") then if ngx.re.find("get,post,put,patch,delete", lower_method, "ijo") then
@ -834,8 +820,7 @@ log_by_lua_block {
spider_stat_fields = request_spider.."="..request_spider.."+"..1 spider_stat_fields = request_spider.."="..request_spider.."+"..1
request_stat_fields = request_stat_fields .. ","..field.."="..field.."+"..1 request_stat_fields = request_stat_fields .. ","..field.."="..field.."+"..1
end end
-- D("Is spider:"..tostring(is_spider==true))
-- D("Request spider:".. tostring(request_spider))
if ipc > 0 then if ipc > 0 then
request_stat_fields = request_stat_fields..",ip=ip+1" request_stat_fields = request_stat_fields..",ip=ip+1"
end end
@ -848,9 +833,19 @@ log_by_lua_block {
end end
local stat_fields = request_stat_fields..";"..client_stat_fields..";"..spider_stat_fields local stat_fields = request_stat_fields..";"..client_stat_fields..";"..spider_stat_fields
-- D("stat_fields:"..stat_fields)
cache_set(server_name, new_id, "stat_fields", stat_fields) local data = {
cache_set(server_name, new_id, "log_kv", json.encode(kv)) server_name = server_name,
stat_fields = stat_fields,
log_kv = kv,
}
local push_data = json.encode(data)
local key = C:getTotalKey()
ngx.shared.mw_total:rpush(key, push_data)
-- cache_set(server_name, new_id, "stat_fields", stat_fields)
-- cache_set(server_name, new_id, "log_kv", json.encode(kv))
end end
local function store_logs_line(db, stmt, input_server_name, lineno) local function store_logs_line(db, stmt, input_server_name, lineno)
@ -970,7 +965,7 @@ log_by_lua_block {
lock_working(input_server_name) lock_working(input_server_name)
local log_dir = "{$SERVER_APP}/logs" local log_dir = "{$SERVER_APP}/logs"
local db_path= log_dir .. '/' .. input_server_name .. "/logs.db" local db_path = log_dir .. '/' .. input_server_name .. "/logs.db"
local db, err = sqlite3.open(db_path) local db, err = sqlite3.open(db_path)
-- if tostring(err) ~= 'nil' then -- if tostring(err) ~= 'nil' then
@ -1025,7 +1020,6 @@ log_by_lua_block {
end end
local res, err = stmt2:finalize() local res, err = stmt2:finalize()
if tostring(res) == "5" then if tostring(res) == "5" then
-- D("Finalize res:"..tostring(res)) -- D("Finalize res:"..tostring(res))
-- D("Finalize err:"..tostring(err)) -- D("Finalize err:"..tostring(err))
@ -1061,7 +1055,7 @@ log_by_lua_block {
load_exclude_ip(server_name) load_exclude_ip(server_name)
cache_logs() cache_logs()
store_logs(server_name) -- store_logs(server_name)
-- D("------------ debug end -------------") -- D("------------ debug end -------------")
end end
@ -1076,7 +1070,7 @@ log_by_lua_block {
end end
) )
if not presult then if not presult then
D("debug error on :"..tostring(err)) C:D("debug error on :"..tostring(err))
return true return true
end end
end end

@ -0,0 +1,24 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
# echo $rootPath
resty=$rootPath/openresty/bin/resty
RUN_CMD=$resty
if [ ! -f $resty ];then
RUN_CMD=/www/server/openresty/bin/resty
fi
# test
# $RUN_CMD simple.lua
$RUN_CMD test_today.lua

@ -0,0 +1,18 @@
local function target()
ngx.re.find("hello, world.", [[\w+\.]], "jo")
end
for i = 1, 100 do
target()
end
collectgarbage()
ngx.update_time()
local begin = ngx.now()
local N = 1e7
for i = 1, N do
target()
end
ngx.update_time()
ngx.say("elapsed: ", (ngx.now() - begin) / N)

@ -0,0 +1,33 @@
local function target()
ngx.re.find("hello, world.", [[\w+\.]], "jo")
end
for i = 1, 100 do
target()
end
-- 以上为预热操作
collectgarbage()
ngx.update_time()
local begin = ngx.now()
local N = 1e6
for i = 1, N do
os.date("%Y%m%d")
-- ngx.say(t)
end
ngx.update_time()
ngx.say("os.date elapsed: ", (ngx.now() - begin) / N)
ngx.update_time()
local begin = ngx.now()
local N = 1e6
for i = 1, N do
ngx.re.gsub(ngx.today(),'-','')
-- ngx.say(t)
end
ngx.update_time()
ngx.say("ngx.today() elapsed: ", (ngx.now() - begin) / N)

@ -0,0 +1,95 @@
# coding:utf-8
import sys
import io
import os
import time
import json
import os
import sys
import time
import string
import json
import hashlib
import shlex
import datetime
import subprocess
import re
from random import Random
TEST_URL = "http://t1.cn/"
# TEST_URL = "https://www.zzzvps.com/"
def httpGet(url, timeout=10):
import urllib.request
try:
req = urllib.request.urlopen(url, timeout=timeout)
result = req.read().decode('utf-8')
return result
except Exception as e:
return str(e)
def httpPost(url, data, timeout=10):
"""
发送POST请求
@url 被请求的URL地址(必需)
@data POST参数可以是字符串或字典(必需)
@timeout 超时时间默认60秒
return string
"""
if sys.version_info[0] == 2:
try:
import urllib
import urllib2
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
data = urllib.urlencode(data)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req, timeout=timeout)
return response.read()
except Exception as ex:
return str(ex)
else:
try:
import urllib.request
import ssl
try:
ssl._create_default_https_context = ssl._create_unverified_context
except:
pass
data = urllib.parse.urlencode(data).encode('utf-8')
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req, timeout=timeout)
result = response.read()
if type(result) == bytes:
result = result.decode('utf-8')
return result
except Exception as ex:
return str(ex)
def test_OK():
'''
目录保存
'''
url = TEST_URL + "ok.txt"
print("ok test start")
url_val = httpGet(url, 10)
print(url_val)
print("ok test end")
def test_start():
test_OK()
if __name__ == "__main__":
os.system('cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/webstats && sh install.sh uninstall 0.2.2 && sh install.sh install 0.2.2')
os.system('cd /Users/midoks/Desktop/mwdev/server/mdserver-web/ && python3 plugins/openresty/index.py stop && python3 plugins/openresty/index.py start')
test_start()

@ -0,0 +1,6 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
python3 index.py
Loading…
Cancel
Save