Blame view

src/services/errorlog.lua 3.2 KB
1be37174   zhouhaihai   error
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)