RoleLog.lua 6.58 KB

-- logType
local LogType = {
	create = "common",
	login = "common",
	logout = "common",
	guide = "common",
	
	in_item = "common",
	out_item = "common",
	in_diamond = "common",
	out_diamond = "common",
	in_hero = "common",
	out_hero = "common",
	in_equip = "common",
	out_equip = "common",
	in_rune = "common",
	out_rune = "common",
	player_exp = "common",
	func_open = "common",
	in_adv = "common",
	out_adv = "common",
	in_artifact = "common",

	mail_action = "common",
	role_action = "common",
	hang_action = "common",
	hero_action = "common",
	adv_action = "common",
	rune_action = "common",
	pvp_action = "common",
	diner_action = "common",
	tower_action = "common",
	gm_action = "common",
	act_action = "common",
}

-- 如要修改 要提前修改 _template mapping -- 对应 mapping 为 gamelog-*
local Mapping = {
	-- 预留一些数据格式  担心integer 范围不够用 将 通用的int* 全部换为long
	common = {
		desc = "keyword",--索引的短字符串
		ucode = "keyword",--关联日志对应ucode
		key1 = "keyword", --可索引的短字符串
		key2 = "keyword", --可索引的短字符串
		-- 几乎不用的长文本 
		text1 = "text",  --长字符串不索引的类型
		-- 五个不同类型的数字 基本上满足数量要求 尽量从低到高用
		short1 = "short", 
		int1 = "long",
		int2 = "long",
		long1 = "long",
		float1 = "float",

		-- 底层使用的 一些参数
		cint1 = "long",
		cint2 = "long",
		cint3 = "long",
	}
}

-- 所有的日志都包括的部分 role 里面的信息  -- mapping 信息在 gamelog-role
local commonRoleField = {
	name = "keyword",
	id = "integer",
	uid = "keyword",
	sid = "short",
	device = "keyword",
	ctime = "integer",
	ltime = "integer",
	level = "short",
	rmbC = "integer",
}

local function printError(info)
	print(info)
	print(debug.traceback())
end

local function checkType(logType, field, value, ctype)
	local typecheckfunc = {
		keyword = function()
			--长度不超过256
			if type(value) ~= "string" then
				value = tostring(value)
				printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [keyword], value : %s", logType, field, value))
			else
				if #value > 256 then
					printError(string.format("LOG ERROR: logType [%s] field [%s] [keyword] type to long. value : %s", logType, field, value))
				end
			end
			return value
		end,
		text = function()
			if type(value) ~= "string" then
				value = tostring(value)
				printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [text], value : %s", logType, field, value))
			end
			return value
		end,
		integer = function()
			if type(value) ~= "number" then
				value = tonumber(value)
				printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], value : %s", logType, field, value))
			end
			if value then
				if math.type(value) ~= "integer" then
					local oldValue = value
					value = math.floor(value)
					if value ~= oldValue then
						printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], is float, value : %s", logType, field, value))
					end
				end
				if -2147483648 > value or value > 2147483647 then
					printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], too big, value : %s", logType, field, value))
					value = nil
				end
			end 
			return value
		end,
		short = function()
			if type(value) ~= "number" then
				value = tonumber(value)
				printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], value : %s", logType, field, value))
			end
			if value then
				if math.type(value) ~= "integer" then
					local oldValue = value
					value = math.floor(value)
					if value ~= oldValue then
						printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], is float, value : %s", logType, field, value))
					end
				end

				if -32768 > value or value > 32768 then
					printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], too big, value : %s", logType, field, value))
					value = nil
				end
			end 
			return value
		end,
		long = function()
			if type(value) ~= "number" then
				value = tonumber(value)
				printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], value : %s", logType, field, value))
			end
			if value then
				if math.type(value) ~= "integer" then
					local oldValue = value
					value = math.floor(value)
					if type(value) ~= "integer" then
						printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], too big, value : %s", logType, field, value))
						value = nil
					elseif value ~= oldValue then
						printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], is float, value : %s", logType, field, value))
					end
				end
			end 
			return value
		end,
		float = function()
			if type(value) ~= "number" then
				value = tonumber(value)
				printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [float], value : %s", logType, field, value))
			end
			return value
		end,
	}

	if typecheckfunc[ctype] then
		return typecheckfunc[ctype]()
	else
		printError(string.format("LOG ERROR: logType [%s] field [%s] have a new type [%s] need add check.", logType, field, ctype))
		return nil
	end
end

local RoleLog = {}
function RoleLog.bind(Role)
	function Role:log(logType, contents)
		contents = contents or {}
		local _logType = LogType[logType]
		if not _logType then 
			printError(string.format("LOG ERROR: new logType [%s] need Add Maping.", logType))
			return 
		end
		local doc = {}
		for field, ctype in pairs(commonRoleField) do
			if contents[field] then
				printError(string.format("LOG ERROR: logType [%s] had field [%s] overwrite default.", logType, field))
			end
			doc[field] = checkType("commonRoleField", field, self:getProperty(field), ctype)
		end

		local mapping = Mapping[_logType]
		if mapping["ucode"] and not contents["ucode"] then
			contents["ucode"] = self:getActionUcode()
		end

		for field, value in pairs(contents) do
			local ftype = mapping[field]
			if ftype then
				doc[field] = checkType(logType, field, value, ftype)
			else
				printError(string.format("LOG ERROR: logType [%s] have new field [%s] no type in mapping.", logType, field))
			end
		end
		if not logd then return end
		pcall(skynet.send, logd, "lua", "log", logType, doc, _logType)
	end

	function Role:startActionUcode()
		if not self._uniqueCount then
			self._uniqueCount = 0
		end
		local action = {self:getProperty("id"), skynet.timex(), self._uniqueCount}
		self._uniqueCount = self._uniqueCount + 1

		self._actionUcode = table.concat(action, "_")
	end

	function Role:endActionUcode()
		self._actionUcode = nil
	end

	function Role:getActionUcode()
		return self._actionUcode
	end

end
return RoleLog