123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- -- 服务端埋点日志服务
- 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 util_record_item = require("utils.util_record_item")
- local moduleData = require("data.module")
- local SEND_COUNT, ACTIVE_SEND_COUNT
- if IS_TEST then
- SEND_COUNT, ACTIVE_SEND_COUNT = 2, 10
- else
- SEND_COUNT, ACTIVE_SEND_COUNT = 50, 100
- end
- local logQueue = {}
- local lTimerLogSync = nil -- 同步日志定时器
- local timeSync = 600 * 100
- -- 资源变化日志
- local itemList = {}
- local timerItem = nil
- 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 _write_to_db(stop)
- -- 销毁定时器
- if timerItem then
- timerItem.delete()
- timerItem = nil
- end
- local count = 0
- if stop then
- count = #itemList
- else
- count = math.min(SEND_COUNT, #itemList)
- end
- local list = {}
- for i = 1, count do
- table.insert(list, table.remove(itemList, 1))
- end
- if #list <= 0 then
- return
- end
- util_record_item:add_item_record(list)
- if #itemList > 0 then
- if timerItem == nil then
- timerItem = create_timeout(timeSync, _write_to_db)
- end
- end
- end
- -- 同步资源日志
- local function l_sync_item_data()
- if #itemList >= SEND_COUNT then
- _write_to_db()
- else
- if timerItem == nil then
- timerItem = create_timeout(timeSync, _write_to_db)
- 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(key, date, cnt)
- local filename = string.format("%s-%s", key, date)
- table.insert(logQueue, {filename = filename, dataStr = cnt})
- l_sync_log_data()
- -- 资源变化
- if key == "resource" then
- table.insert(itemList, cnt)
- l_sync_item_data()
- end
- 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 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")
|