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
  
  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"
51852b2e   liuzujun   修改日志相关env为ob
25
  			doc["env"] = "ob"
1be37174   zhouhaihai   error
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
  			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)