关于增加skynet_fly 日志服务

前言

最近在skynet_fly_demo中尝试用skynet_fly后台管理,想通过后台监控服务器的历史运行状况,服务实时信息错误日志报警,等等。历史运行状况,服务实时信息这两个通过skynet的debug_console再加上我封装的集群,很方便的就做好了。之后考虑错误日志报警的问题,错误日志分为主动打印的异常日志被动触发lua断言错误

  1. 主动打印的异常日志 这个好解决,我封装的log模块提供了hook钩子函数,可以截获到日志打印。
  2. 被动触发lua断言错误 由于在c层调用的pcall断言直接调用的skynet_error日志打印,没有经过我的自定义log模块,没办法截获。目前能想到的有两种方案。
    1. 修改luadispath消息分发的地方,再用一次pcall包裹,出错后使用log模块打印日志。
      优点
      可以使用c层的log服务,效率高一些。
      缺点
      截获点是发送日志消息的服务,截获点分散。
    2. lua层实现log服务,这样所有日志都可以截获处理了。
      优点
      截获点统一。
      缺点
      lua效率慢一些。

由于日志报警功能通常都需要做CD,相同的异常都不会让它一直报,所以我选择第二种方案。

实现

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
local skynet = require "skynet"
local skynet_util = require "skynet_util"
local file_util = require "file_util"
local time_util = require "time_util"
require "skynet.manager"

local os = os
local io = io
local error = error
local assert = assert
local print = print
local string = string
local math_floor = math.floor
local type = type
local table = table

local SELF_ADDRESS = skynet.self()

local file = nil
local file_path = skynet.getenv('logpath')
local file_name = skynet.getenv('logfilename')
local daemon = skynet.getenv('daemon')
local hook_hander_list = {}

local function open_file()
if not daemon then
return
end
if file then
file:close()
end
print(file_path,file_name)
os.execute('mkdir -p ' .. file_path)
if not os.execute("mkdir -p " .. file_path) then
error("create dir err")
end
local file_p = file_util.path_join(file_path,file_name)
file = io.open(file_p, 'a+')
assert(file, "can`t open file " .. file_p)
end

skynet.register_protocol {
name = "text",
id = skynet.PTYPE_TEXT,
unpack = skynet.tostring,
dispatch = function(_, address, msg)
local cur_time = time_util.skynet_int_time()
local second,m = math_floor(cur_time / 100), cur_time % 100
local time_date = os.date('[%Y%m%d:%H:%M:%S ',second)
local log_str = time_date .. m .. ']' .. msg
if file then
file:write(log_str .. '\n')
file:flush()
else
print(log_str)
end

if address ~= SELF_ADDRESS then
for i = 1,#hook_hander_list do
hook_hander_list[i](msg)
end
end
end
}

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

local CMD = {}

function CMD.add_hook(file_name)
local func = require(file_name)
assert(type(func) == 'function', "err file " .. file_name)
table.insert(hook_hander_list, func)
return true
end

skynet.start(function()
open_file()
skynet_util.lua_dispatch(CMD,{})
end)

只需要lua的log服务新增一个add_hook命令。需要截获调用命令即可。

总结

通过增加log日志服务并且提供截获处理的方式,进一步提高了skynet_fly框架的业务灵活性。

skynetfly源码地址


关于增加skynet_fly 日志服务
https://huahua132.github.io/2023/11/19/skynet_fly_ss/logservice/
作者
huahua132
发布于
2023年11月19日
许可协议