errorlog.lua 3.2 KB

local skynet = require "skynet"
local socketdriver = require "skynet.socketdriver"
local serverId = tonumber(skynet.getenv("servId"))

require "shared.init"
require "skynet.manager"

local table_insert = table.insert
local pairs = pairs
local ipairs = ipairs
local string_format = string.format

local logHandle = {
	log = {
		host = "127.0.0.1",
		port = 13003,
		handle = function(doc, address, msg)
			-- 注入字段
			local now = skynet.timex()
			doc["time"] = now
			doc["timestamp"] = now
			doc["instance_id"] = serverId
			doc["game_name"] = "wasteland"
			doc["env"] = "cb"
			doc["app_name"] = "gs"
			doc["app_id"] = "game.wasteland.gs"
			--FATAL、ERROR、WARN、INFO、DEBUG
			doc["level"] = "ERROR"
			doc["log"] = msg
			doc["address"] = string_format(":%08x", address)
		end
	},
}

local connect_relation = {}
local function getConInfo(fd)
	return logHandle[connect_relation[fd] or ""]
end



local socket_message = {}
-- read skynet_socket.h for these macro
-- SKYNET_SOCKET_TYPE_DATA = 1
socket_message[1] = function(id, size, data)
	skynet.error(string.format("LOG SOCKET: data: ", skynet.tostring(data, size)))
	socketdriver.drop(data, size)
end

-- SKYNET_SOCKET_TYPE_CONNECT = 2
socket_message[2] = function(id, _ , addr)
	local cur = getConInfo(id)
	skynet.error("LOG SOCKET: connect: ", addr)
	cur.connected = true
	cur.connecting = false
end

-- SKYNET_SOCKET_TYPE_CLOSE = 3
socket_message[3] = function(id)
	skynet.error("LOG SOCKET: closed")
	local cur = getConInfo(id)
	if not cur then return end
	cur.connected = false
	cur.connecting = false
	connect_relation[id] = nil
end

-- SKYNET_SOCKET_TYPE_ERROR = 5
socket_message[5] = function(id, _, err)
	skynet.error("LOG SOCKET: error: ", err)
	local cur = getConInfo(id)
	if not cur then return end
	cur.connected = false
	cur.connecting = false
	connect_relation[id] = nil
end



local function open()
	for logTo, data in pairs(logHandle) do
		if not data.connecting  and not data.connected then
			data.connecting = true
			data.fd = socketdriver.connect(data.host, data.port)
			connect_relation[data.fd] = logTo
		end
	end
end

local function log(address, msg, logTo)
	logTo = logTo or "log"
	-- print(string.format(":%08x(%.2f): %s", address, skynet.time(), msg))
	local cur = logHandle[logTo] 
	if not cur then
		print("error log to ", logTo)
	end
	local doc = {}
	if cur.handle then
		cur.handle(doc, address, msg)
	end
	if cur.connected and cur.fd then
		socketdriver.send(cur.fd, json.encode(doc) .. "\n")
	else
		-- 断线会丢失一部分日志
		if not cur.connecting then
			open() -- 连一下
		end
	end
end


skynet.register_protocol {
	name = "socket",
	id = skynet.PTYPE_SOCKET,	-- PTYPE_SOCKET = 6
	unpack = socketdriver.unpack,
	dispatch = function (_, _, t, ...)
		if socket_message[t] then
			socket_message[t](...)
		end
	end
}

-- register protocol text before skynet.start would be better.
skynet.register_protocol {
	name = "text",
	id = skynet.PTYPE_TEXT,
	unpack = skynet.tostring,
	dispatch = function(_, address, msg)
		log(address, msg)
	end
}

skynet.register_protocol {
	name = "SYSTEM",
	id = skynet.PTYPE_SYSTEM,
	unpack = function(...) return ... end,
	dispatch = function()
		-- reopen signal
		print("SIGHUP")
	end
}

open()
skynet.start(function()end)