2022-07-18 13:54:10 -04:00
|
|
|
|
log_by_lua_block {
|
2026-07-02 02:01:50 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
webstats_log.lua - WebStats 日志采集模块
|
|
|
|
|
|
=========================================
|
|
|
|
|
|
|
|
|
|
|
|
本模块在 Nginx 的 log_by_lua_block 阶段执行,负责:
|
|
|
|
|
|
- 采集请求日志数据
|
|
|
|
|
|
- 过滤不需要统计的请求
|
|
|
|
|
|
- 识别爬虫和客户端类型
|
|
|
|
|
|
- 计算 PV/UV/IP 等指标
|
|
|
|
|
|
- 将日志数据发送到共享内存队列
|
|
|
|
|
|
|
|
|
|
|
|
执行时机:每次请求完成后(log_by_lua_block 阶段)
|
|
|
|
|
|
|
|
|
|
|
|
主要数据流向:
|
|
|
|
|
|
请求完成 -> log_by_lua_block -> 数据采集 -> 过滤处理 -> 爬虫/客户端识别 -> 统计计算 -> 入队
|
|
|
|
|
|
|
|
|
|
|
|
依赖模块:
|
|
|
|
|
|
- cjson: JSON 编解码
|
|
|
|
|
|
- webstats_common: 核心工具模块
|
|
|
|
|
|
- webstats_config: 全局配置
|
|
|
|
|
|
- webstats_sites: 站点配置
|
|
|
|
|
|
]]
|
2022-07-18 13:54:10 -04:00
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 添加 Lua 模块搜索路径
|
2022-07-18 23:59:11 -04:00
|
|
|
|
local cpath = "{$SERVER_APP}/lua/"
|
|
|
|
|
|
if not package.cpath:find(cpath) then
|
|
|
|
|
|
package.cpath = cpath .. "?.so;" .. package.cpath
|
|
|
|
|
|
end
|
|
|
|
|
|
if not package.path:find(cpath) then
|
|
|
|
|
|
package.path = cpath .. "?.lua;" .. package.path
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 调试模式开关
|
2022-10-16 12:44:04 -04:00
|
|
|
|
local debug_mode = true
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 引入核心模块(单例模式)
|
2022-10-16 12:44:04 -04:00
|
|
|
|
local __C = require "webstats_common"
|
|
|
|
|
|
local C = __C:getInstance()
|
2022-07-18 13:54:10 -04:00
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 依赖模块
|
2022-07-19 11:02:05 -04:00
|
|
|
|
local json = require "cjson"
|
2022-10-16 12:44:04 -04:00
|
|
|
|
local config = require "webstats_config"
|
|
|
|
|
|
local sites = require "webstats_sites"
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 获取站点名称(通过域名匹配)
|
2023-02-11 08:42:57 -05:00
|
|
|
|
local server_name = C:get_sn(ngx.var.server_name)
|
2022-11-30 23:33:09 -05:00
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 设置配置数据
|
2022-10-16 12:44:04 -04:00
|
|
|
|
C:setConfData(config, sites)
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 获取合并后的站点配置
|
2022-10-17 09:12:42 -04:00
|
|
|
|
local auto_config = C:setInputSn(server_name)
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 获取请求头部和方法
|
2022-10-17 11:29:57 -04:00
|
|
|
|
local request_header = ngx.req.get_headers()
|
|
|
|
|
|
local method = ngx.req.get_method()
|
|
|
|
|
|
|
2026-07-02 02:12:32 -04:00
|
|
|
|
-- 共享内存字典实例(必须在使用前定义)
|
|
|
|
|
|
local cache = ngx.shared.mw_total
|
|
|
|
|
|
-- 日志队列键名
|
|
|
|
|
|
local total_key = "log_kv_total"
|
|
|
|
|
|
|
|
|
|
|
|
--[[
|
|
|
|
|
|
状态码过滤表
|
|
|
|
|
|
需要记录详细信息的状态码(4xx 和 5xx 错误)
|
|
|
|
|
|
]]
|
|
|
|
|
|
local status_codes_to_log = {
|
|
|
|
|
|
["400"] = true, ["401"] = true, ["402"] = true, ["403"] = true, ["404"] = true,
|
|
|
|
|
|
["405"] = true, ["406"] = true, ["407"] = true, ["408"] = true, ["409"] = true,
|
|
|
|
|
|
["410"] = true, ["411"] = true, ["412"] = true, ["413"] = true, ["414"] = true,
|
|
|
|
|
|
["415"] = true, ["416"] = true, ["417"] = true, ["418"] = true, ["421"] = true,
|
|
|
|
|
|
["422"] = true, ["423"] = true, ["424"] = true, ["425"] = true, ["426"] = true,
|
|
|
|
|
|
["449"] = true, ["451"] = true, ["499"] = true, ["500"] = true, ["501"] = true,
|
|
|
|
|
|
["502"] = true, ["503"] = true, ["504"] = true, ["505"] = true, ["506"] = true,
|
|
|
|
|
|
["507"] = true, ["509"] = true, ["510"] = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
--[[
|
|
|
|
|
|
HTTP 方法过滤表
|
|
|
|
|
|
需要统计的 HTTP 方法
|
|
|
|
|
|
]]
|
|
|
|
|
|
local http_methods = {["get"] = true, ["post"] = true, ["put"] = true, ["patch"] = true, ["delete"] = true}
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
排除函数模块
|
2026-07-02 02:12:32 -04:00
|
|
|
|
============
|
2026-07-02 01:54:31 -04:00
|
|
|
|
|
|
|
|
|
|
以下函数用于判断请求是否应该被排除(不统计),包括:
|
|
|
|
|
|
- IP 排除:全局和站点级别的排除 IP
|
|
|
|
|
|
- 状态码排除:指定状态码的请求不统计
|
|
|
|
|
|
- 扩展名排除:指定扩展名的文件不统计
|
|
|
|
|
|
- URL 排除:指定 URL 路径不统计
|
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
|
|
--[[
|
|
|
|
|
|
加载全局排除 IP 列表到缓存
|
|
|
|
|
|
将配置中的全局排除 IP 存入共享内存,避免每次请求都读取配置
|
|
|
|
|
|
]]
|
2022-07-21 06:13:32 -04:00
|
|
|
|
local function load_global_exclude_ip()
|
|
|
|
|
|
local load_key = "global_exclude_ip_load"
|
2022-07-26 11:06:24 -04:00
|
|
|
|
local global_exclude_ip = auto_config["exclude_ip"]
|
2022-07-21 06:13:32 -04:00
|
|
|
|
if global_exclude_ip then
|
2026-07-02 01:54:31 -04:00
|
|
|
|
for _, _ip in pairs(global_exclude_ip) do
|
|
|
|
|
|
if not cache:get("global_exclude_ip_" .. _ip) then
|
|
|
|
|
|
cache:set("global_exclude_ip_" .. _ip, true)
|
2022-07-21 06:13:32 -04:00
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
cache:set(load_key, true)
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
加载站点级排除 IP 列表到缓存
|
|
|
|
|
|
@param input_server_name string 站点名称
|
|
|
|
|
|
@return boolean 是否成功
|
|
|
|
|
|
]]
|
2022-07-21 06:13:32 -04:00
|
|
|
|
local function load_exclude_ip(input_server_name)
|
|
|
|
|
|
local load_key = input_server_name .. "_exclude_ip_load"
|
|
|
|
|
|
local site_config = config[input_server_name]
|
|
|
|
|
|
|
|
|
|
|
|
local site_exclude_ip = nil
|
|
|
|
|
|
if site_config then
|
|
|
|
|
|
site_exclude_ip = site_config["exclude_ip"]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
if site_exclude_ip then
|
2026-07-02 01:54:31 -04:00
|
|
|
|
for _, _ip in pairs(site_exclude_ip) do
|
|
|
|
|
|
cache:set(input_server_name .. "_exclude_ip_" .. _ip, true)
|
2022-07-21 06:13:32 -04:00
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
cache:set(load_key, true)
|
|
|
|
|
|
return true
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
根据状态码判断是否排除
|
|
|
|
|
|
检查当前请求的状态码是否在排除列表中
|
|
|
|
|
|
@return boolean 是否排除
|
|
|
|
|
|
]]
|
2022-07-21 06:13:32 -04:00
|
|
|
|
local function filter_status()
|
2022-07-26 11:06:24 -04:00
|
|
|
|
if not auto_config['exclude_status'] then return false end
|
2022-07-20 12:41:02 -04:00
|
|
|
|
local the_status = tostring(ngx.status)
|
2026-07-02 01:54:31 -04:00
|
|
|
|
for _, v in ipairs(auto_config['exclude_status']) do
|
2022-07-20 12:41:02 -04:00
|
|
|
|
if the_status == v then
|
|
|
|
|
|
return true
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
return false
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
根据文件扩展名判断是否排除
|
|
|
|
|
|
检查请求的 URI 是否以排除的扩展名结尾
|
|
|
|
|
|
@return boolean 是否排除
|
|
|
|
|
|
]]
|
2022-07-20 12:41:02 -04:00
|
|
|
|
local function exclude_extension()
|
2026-07-02 00:52:05 -04:00
|
|
|
|
local uri = ngx.var.uri
|
|
|
|
|
|
if not uri then return false end
|
|
|
|
|
|
|
|
|
|
|
|
local exclude_ext = auto_config['exclude_extension']
|
|
|
|
|
|
if not exclude_ext then return false end
|
|
|
|
|
|
|
|
|
|
|
|
local lower_uri = string.lower(uri)
|
|
|
|
|
|
for _, ext in ipairs(exclude_ext) do
|
|
|
|
|
|
if string.find(lower_uri, "." .. ext .. "$", 1, true) then
|
2022-07-20 12:41:02 -04:00
|
|
|
|
return true
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
return false
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
根据 URL 判断是否排除
|
|
|
|
|
|
支持精确匹配和正则匹配两种模式
|
|
|
|
|
|
@return boolean 是否排除
|
|
|
|
|
|
]]
|
2022-07-20 12:41:02 -04:00
|
|
|
|
local function exclude_url()
|
2026-07-02 00:52:05 -04:00
|
|
|
|
local request_uri = ngx.var.request_uri
|
|
|
|
|
|
if not request_uri then return false end
|
|
|
|
|
|
|
|
|
|
|
|
local url_conf = auto_config['exclude_url']
|
|
|
|
|
|
if not url_conf then return false end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 去掉开头的 '/'
|
2026-07-02 00:52:05 -04:00
|
|
|
|
local the_uri = string.sub(request_uri, 2)
|
|
|
|
|
|
for _, conf in ipairs(url_conf) do
|
2022-07-20 12:41:02 -04:00
|
|
|
|
local mode = conf["mode"]
|
|
|
|
|
|
local url = conf["url"]
|
|
|
|
|
|
if mode == "regular" then
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 正则匹配模式
|
2022-07-20 12:41:02 -04:00
|
|
|
|
if ngx.re.find(the_uri, url, "ijo") then
|
|
|
|
|
|
return true
|
|
|
|
|
|
end
|
|
|
|
|
|
else
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 精确匹配模式
|
2022-07-20 12:41:02 -04:00
|
|
|
|
if the_uri == url then
|
|
|
|
|
|
return true
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
return false
|
|
|
|
|
|
end
|
2022-07-21 06:13:32 -04:00
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
根据 IP 判断是否排除
|
|
|
|
|
|
先检查站点级排除 IP,再检查全局排除 IP
|
|
|
|
|
|
@param input_server_name string 站点名称
|
|
|
|
|
|
@param ip string 客户端 IP
|
|
|
|
|
|
@return boolean 是否排除
|
|
|
|
|
|
]]
|
2022-07-21 06:13:32 -04:00
|
|
|
|
local function exclude_ip(input_server_name, ip)
|
|
|
|
|
|
local site_config = config[input_server_name]
|
|
|
|
|
|
if site_config then
|
2026-07-02 00:52:05 -04:00
|
|
|
|
local server_exclude_ips = site_config["exclude_ip"]
|
|
|
|
|
|
if server_exclude_ips then
|
|
|
|
|
|
for _, _ip in pairs(server_exclude_ips) do
|
|
|
|
|
|
if cache:get(input_server_name .. "_exclude_ip_" .. ip) then
|
|
|
|
|
|
return true
|
|
|
|
|
|
end
|
|
|
|
|
|
break
|
|
|
|
|
|
end
|
2022-07-21 06:13:32 -04:00
|
|
|
|
end
|
|
|
|
|
|
end
|
2026-07-02 00:52:05 -04:00
|
|
|
|
|
|
|
|
|
|
return cache:get("global_exclude_ip_" .. ip) ~= nil
|
2022-07-21 06:13:32 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
日志采集函数
|
|
|
|
|
|
采集请求数据,识别爬虫/客户端,计算统计指标,然后入队
|
|
|
|
|
|
|
|
|
|
|
|
执行流程:
|
|
|
|
|
|
1. 获取日志 ID 和客户端 IP
|
|
|
|
|
|
2. 判断是否需要排除(状态码/扩展名/URL/IP)
|
|
|
|
|
|
3. 构建 IP 列表(含代理链)
|
|
|
|
|
|
4. 采集请求数据(URI、状态码、响应大小等)
|
|
|
|
|
|
5. 构建日志记录
|
|
|
|
|
|
6. 识别爬虫/客户端类型
|
|
|
|
|
|
7. 计算 PV/UV/IP 指标
|
|
|
|
|
|
8. 将数据入队到共享内存
|
|
|
|
|
|
|
|
|
|
|
|
@param input_sn string 站点名称
|
|
|
|
|
|
]]
|
|
|
|
|
|
local function cache_logs(input_sn)
|
|
|
|
|
|
-- 获取日志唯一 ID
|
2022-10-18 04:38:18 -04:00
|
|
|
|
local new_id = C:get_last_id(input_sn)
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 获取客户端真实 IP(支持 CDN 转发)
|
2022-10-18 04:38:18 -04:00
|
|
|
|
local ip = C:get_client_ip()
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 判断是否排除(状态码/扩展名/URL/IP)
|
2026-07-02 00:52:05 -04:00
|
|
|
|
local excluded = filter_status() or exclude_extension() or exclude_url() or exclude_ip(input_sn, ip)
|
2022-10-18 04:38:18 -04:00
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 构建 IP 列表(包含代理链)
|
2022-10-18 04:38:18 -04:00
|
|
|
|
local ip_list = request_header["x-forwarded-for"]
|
|
|
|
|
|
if ip and not ip_list then
|
|
|
|
|
|
ip_list = ip
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local remote_addr = ngx.var.remote_addr
|
2023-11-17 13:36:18 -05:00
|
|
|
|
if "table" == type(ip_list) then
|
2026-07-02 00:52:05 -04:00
|
|
|
|
ip_list = json.encode(ip_list)
|
|
|
|
|
|
end
|
2023-11-17 13:36:18 -05:00
|
|
|
|
|
2026-07-02 00:52:05 -04:00
|
|
|
|
if remote_addr and not string.find(ip_list, remote_addr, 1, true) then
|
|
|
|
|
|
ip_list = ip_list .. "," .. remote_addr
|
2022-10-18 04:38:18 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 采集请求数据
|
|
|
|
|
|
local request_time = C:get_request_time() -- 请求耗时(毫秒)
|
|
|
|
|
|
local client_port = ngx.var.remote_port -- 客户端端口
|
|
|
|
|
|
local uri = tostring(ngx.var.uri) -- 请求路径
|
|
|
|
|
|
local status_code = ngx.status -- 状态码
|
|
|
|
|
|
local protocol = ngx.var.server_protocol -- 协议(HTTP/1.1 等)
|
|
|
|
|
|
local request_uri = ngx.var.request_uri -- 完整请求路径(含参数)
|
|
|
|
|
|
local body_length = C:get_length() -- 响应体大小
|
|
|
|
|
|
local domain = C:get_domain() -- 域名
|
|
|
|
|
|
local referer = ngx.var.http_referer -- 来源页
|
|
|
|
|
|
local user_agent = request_header['user-agent'] -- 用户代理
|
|
|
|
|
|
local now_time = ngx.time() -- 当前时间戳
|
|
|
|
|
|
|
|
|
|
|
|
-- 构建日志记录
|
2022-10-18 04:38:18 -04:00
|
|
|
|
local kv = {
|
2026-07-02 00:52:05 -04:00
|
|
|
|
id = new_id,
|
2026-07-02 01:54:31 -04:00
|
|
|
|
time_key = os.date("%Y%m%d%H", now_time), -- 小时级存储键
|
2026-07-02 00:52:05 -04:00
|
|
|
|
time = now_time,
|
|
|
|
|
|
ip = ip,
|
|
|
|
|
|
domain = domain,
|
|
|
|
|
|
server_name = input_sn,
|
|
|
|
|
|
real_server_name = input_sn,
|
|
|
|
|
|
method = method,
|
|
|
|
|
|
status_code = status_code,
|
|
|
|
|
|
uri = uri,
|
|
|
|
|
|
request_uri = request_uri,
|
|
|
|
|
|
body_length = body_length,
|
|
|
|
|
|
referer = referer,
|
|
|
|
|
|
user_agent = user_agent,
|
|
|
|
|
|
protocol = protocol,
|
2026-07-02 01:54:31 -04:00
|
|
|
|
is_spider = 0, -- 是否爬虫
|
2026-07-02 00:52:05 -04:00
|
|
|
|
request_time = request_time,
|
2026-07-02 01:54:31 -04:00
|
|
|
|
excluded = excluded, -- 是否排除
|
|
|
|
|
|
request_headers = '', -- 请求头(异常时记录)
|
|
|
|
|
|
ip_list = ip_list, -- IP 列表(含代理链)
|
2026-07-02 00:52:05 -04:00
|
|
|
|
client_port = client_port
|
2022-10-18 04:38:18 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 初始化统计字段
|
2026-07-02 00:52:05 -04:00
|
|
|
|
local request_stat_fields = {req = 1, length = body_length}
|
2022-10-18 04:38:18 -04:00
|
|
|
|
local spider_stat_fields = {}
|
|
|
|
|
|
local client_stat_fields = {}
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 非排除请求的额外处理
|
2022-10-18 04:38:18 -04:00
|
|
|
|
if not excluded then
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 记录异常请求的原始数据(500/POST/403)
|
2026-07-02 00:52:05 -04:00
|
|
|
|
if status_code == 500 or (method == "POST" and config['global']["record_post_args"] == true) or (status_code == 403 and config['global']["record_get_403_args"] == true) then
|
|
|
|
|
|
local ok, data = pcall(function() return C:get_http_origin() end)
|
|
|
|
|
|
if ok and data then
|
2022-10-18 04:38:18 -04:00
|
|
|
|
kv["request_headers"] = data
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 统计状态码
|
2026-07-02 00:52:05 -04:00
|
|
|
|
if status_codes_to_log[tostring(status_code)] then
|
|
|
|
|
|
request_stat_fields["status_" .. status_code] = 1
|
2022-10-18 04:38:18 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 统计 HTTP 方法
|
2022-10-18 04:38:18 -04:00
|
|
|
|
local lower_method = string.lower(method)
|
2026-07-02 00:52:05 -04:00
|
|
|
|
if http_methods[lower_method] then
|
|
|
|
|
|
request_stat_fields["http_" .. lower_method] = 1
|
2022-10-18 04:38:18 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 识别爬虫/客户端
|
2026-07-02 00:52:05 -04:00
|
|
|
|
local is_spider, request_spider, spider_index = C:match_spider(user_agent)
|
|
|
|
|
|
if not is_spider then
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 非爬虫:识别客户端类型,计算 PV/UV/IP
|
2026-07-02 00:52:05 -04:00
|
|
|
|
client_stat_fields = C:match_client_arr(user_agent)
|
|
|
|
|
|
local pvc, uvc = C:statistics_request(ip, is_spider, body_length)
|
|
|
|
|
|
local ipc = C:statistics_ipc(input_sn, ip)
|
|
|
|
|
|
|
|
|
|
|
|
if ipc > 0 then request_stat_fields["ip"] = 1 end
|
|
|
|
|
|
if uvc > 0 then request_stat_fields["uv"] = 1 end
|
|
|
|
|
|
if pvc > 0 then request_stat_fields["pv"] = 1 end
|
2022-10-18 04:38:18 -04:00
|
|
|
|
else
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 爬虫:记录爬虫类型
|
2022-10-18 04:38:18 -04:00
|
|
|
|
kv["is_spider"] = spider_index
|
|
|
|
|
|
spider_stat_fields[request_spider] = 1
|
2026-07-02 00:52:05 -04:00
|
|
|
|
request_stat_fields["spider"] = 1
|
2022-10-18 04:38:18 -04:00
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 构建最终数据结构
|
2022-10-17 12:56:31 -04:00
|
|
|
|
local data = {
|
2026-07-02 00:52:05 -04:00
|
|
|
|
server_name = input_sn,
|
|
|
|
|
|
stat_fields = {
|
|
|
|
|
|
request_stat_fields = request_stat_fields,
|
|
|
|
|
|
client_stat_fields = client_stat_fields,
|
|
|
|
|
|
spider_stat_fields = spider_stat_fields,
|
|
|
|
|
|
},
|
|
|
|
|
|
log_kv = kv,
|
2022-10-17 12:56:31 -04:00
|
|
|
|
}
|
2022-10-16 12:44:04 -04:00
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 入队到共享内存队列
|
2026-07-02 00:52:05 -04:00
|
|
|
|
cache:rpush(total_key, json.encode(data))
|
2022-07-19 11:02:05 -04:00
|
|
|
|
end
|
2022-07-19 02:18:37 -04:00
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
应用入口函数
|
|
|
|
|
|
加载排除 IP 列表,然后采集日志
|
|
|
|
|
|
]]
|
2022-07-18 13:54:10 -04:00
|
|
|
|
local function run_app()
|
2022-07-21 06:13:32 -04:00
|
|
|
|
load_global_exclude_ip()
|
|
|
|
|
|
load_exclude_ip(server_name)
|
2022-10-17 09:12:42 -04:00
|
|
|
|
cache_logs(server_name)
|
2022-07-19 11:02:05 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
--[[
|
|
|
|
|
|
应用入口包装函数(带错误捕获)
|
|
|
|
|
|
在调试模式下,使用 pcall 捕获异常并记录日志
|
|
|
|
|
|
]]
|
2022-07-19 11:02:05 -04:00
|
|
|
|
local function run_app_ok()
|
|
|
|
|
|
if not debug_mode then return run_app() end
|
2022-07-18 13:54:10 -04:00
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
local presult, err = pcall(function() run_app() end)
|
2022-07-18 13:54:10 -04:00
|
|
|
|
if not presult then
|
2026-07-02 01:54:31 -04:00
|
|
|
|
C:D("debug error on :" .. tostring(err))
|
2022-07-18 13:54:10 -04:00
|
|
|
|
return true
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-07-02 01:54:31 -04:00
|
|
|
|
-- 执行应用
|
2022-07-19 11:02:05 -04:00
|
|
|
|
return run_app_ok()
|
2022-07-18 13:54:10 -04:00
|
|
|
|
}
|
|
|
|
|
|
|