errorlog.lua
3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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)