-- 服务端埋点日志服务 local skynet = require "skynet" local nodeMgr = require "nodeMgr" local baseService = require("baseService") local timeUtil = require "utils.timeUtil" local serverLogUtil = require "utils.serverLogUtil" local lib_game_redis = require("lib_game_redis") local moduleData = require("data.module") local SEND_COUNT, ACTIVE_SEND_COUNT if IS_TEST then SEND_COUNT, ACTIVE_SEND_COUNT = 1, 10 else SEND_COUNT, ACTIVE_SEND_COUNT = 50, 100 end local logQueue = {} local lTimerLogSync = nil -- 同步日志定时器 local timeSync = 600 * 100 local tabKeyFind = table.key_find local logAddr local function l_sned_logs_to_resource(logList) logAddr = logAddr or nodeMgr.query_node_service_addr("resource", ".server_log") nodeMgr.send("resource", logAddr, "writeLogList", logList) end -- 发送日志 local function l_send_log(stop) -- 销毁定时器 if lTimerLogSync then lTimerLogSync.delete() lTimerLogSync = nil end local count = 0 if stop then count = #logQueue else count = math.min(SEND_COUNT, #logQueue) end local data = {} for i = 1, count do table.insert(data, table.remove(logQueue, 1)) end if #data <= 0 then return end l_sned_logs_to_resource(data) end -- 同步日志 local function l_sync_log_data() if #logQueue >= SEND_COUNT then l_send_log() else if lTimerLogSync == nil then lTimerLogSync = create_timeout(timeSync, l_send_log) end end end local function l_sync_active_log_data(filename, dataStr) l_sned_logs_to_resource({{filename = filename, dataStr = dataStr}}) end local root = {} function root.add_file_log(filename, dataStr) table.insert(logQueue, {filename = filename, dataStr = dataStr}) l_sync_log_data() end -- 活跃用户埋点 local bagData = require("data.bag") local function l_log_user_active(uid, date) local lastLoginTime = timeUtil.toString(moduleData:hget_int(uid, "player", "lastLoginTime")) local mainProgress = "" do local maxChapterId = moduleData:hget_int(uid, "tb_pve_stars", "maxChapterId") or 1 -- local passLevel = moduleData:hget_int(uid, "tb_pve_stars", "passLevel") or 0 -- mainProgress = maxChapterId .. "-" .. passLevel end local data = { date, uid or 0, moduleData:get_channel(uid) or "", -- 渠道 bagData:get_item_count(uid, 101), -- 金币持有量 bagData:get_item_count(uid, 102), -- 钻石持有量 lastLoginTime, -- 最后一次登录时间 moduleData:get_nickname(uid) } return serverLogUtil.formatData(data) end -- 生成活跃用户日志(每日统计) local function l_log_day_before_active() local now = skynet_time() local logDate = timeUtil.toDate(now - 24 * 3600) local key = serverLogUtil.getActiveKey(logDate) local uidList = lib_game_redis:smembers(key) if is_empty(uidList) then return end log.warning("生成活跃用户日志 开始时间:%s", now) local filename = string.format("user-%s", logDate) local count, list = 0, {} for _, uid in ipairs(uidList) do count = count + 1 local ok, actStr = pcall(l_log_user_active, tonumber(uid), logDate) if not ok then log.error("生成活跃用户日志error uid:%s err:%s", uid, actStr) else table.insert(list, actStr) end if count >= ACTIVE_SEND_COUNT then l_sync_active_log_data(filename, table.concat(list, "\n")) count, list = 0, {} skynet.sleep(10) end end if count > 0 then l_sync_active_log_data(filename, table.concat(list, "\n")) end log.error("生成活跃用户日志 结束时间:%s", skynet_time()) -- 暂时先保存日志 local newKey = string.format("%s:%s", "old", key) lib_game_redis:rename(key, newKey) end local function l_timer_next_day() -- 生成昨日活跃用户数据 l_log_day_before_active() local now = skynet_time() local timeDiff = (timeUtil.getUnixtimeTomorrow() - now) + 60 -- 现在到第二天1分 create_timeout(timeDiff * 100, l_timer_next_day) end function root.onStart() local nodename = skynet.getenv("nodeName") if nodename == "clientlog" then -- 每日 0 点在线统计 l_timer_next_day() end end function root.onStop() l_send_log(true) end baseService.start(root, "statisticLog")