希望在 debug 的 STAT 指令返回值中添加服务名以及服务启动参数以方便调试和监控
tqing1128 opened this issue · comments
无论是 debug_console 还是自定义的监控服务中,都必须 LIST 和 STAT 一起配合使用才可以定位,而 STAT 返回值中增加服务名几乎不产生消耗,加服务启动参数需要额外处理。
我觉得可以提 pr ,mem 指令也带上名字了
STAT 和 MEM 不同在于 STAT 中每一项都是 table, MEM 是字符串,在 debug_console 可视化中 table 中每一项的显示顺序好像没有规则,STAT 中每一项最后显示的是 task:0,服务启动参数长短不一,放在最后比较合适(MEM 也是这样做的),有两种方案:
1、服务启动参数项以 t 字母开头可以显示在最后,但是这种实现比较奇怪
2、将每一项 table 都 format 成字符串,和 MEM 一样
我个人偏向第二种,但是不明确现有方案为什么没有这样做
建议另外写监控工具,debug console 和程序脚本对接。
调试的时候也经常会在 debug console 用 stat 查看信息
我的意思是,即使调试,也可以用额外的脚本去解析。debug console 支持用 http 协议 GET ,就是为了方便做这样的脚本取数据。
用额外的脚本从 debug console 中获取数据,按自己的需求整合并输出,减少不必要的指令输入,灵活高效。只是需要写一个 debug console 返回值(字符串)解析方法。是这个意思吗?
是的。这样你可以根据需要 cache 住名称等信息,不必重复查询。解析字符串相对容易,另外可以调用现成的 curl 等程序来编写脚本。
明白了,谢谢
我的意思是,即使调试,也可以用额外的脚本去解析。debug console 支持用 http 协议 GET ,就是为了方便做这样的脚本取数据。
这个有示例吗?想做一些工具来支持debug一些相关命令。比如通过http注入inject某个服务
项目中难免会需要新增一些特殊指令,可以参考下这个无侵入式扩展 debug_console 服务的 demo 。
https://github.com/hanxi/skynet-demo#无侵入式扩展官方的-debug_console-服务
@sue602 http 接口的使用示例我加到 wiki 里了 https://github.com/cloudwu/skynet/wiki/DebugConsole
如果你想通过 http 接口使用 inject 指令可以这样写(下面示例是对 debug_console 服务 inject):
> curl --http0.9 'http://127.0.0.1:8000/list'
Welcome to skynet console
:01000004 snlua cmaster
:01000005 snlua cslave
:01000007 snlua datacenterd
:01000008 snlua service_mgr
:0100000a snlua protoloader
:0100000b snlua console
:0100000c snlua debug_console 8000
:0100000d snlua simpledb
:0100000e snlua watchdog
:0100000f snlua gate
<CMD OK>
> curl --http0.9 'http://127.0.0.1:8000/stat'
Welcome to skynet console
:01000004 cpu:0.001628 message:10 mqlen:0 task:1
:01000005 cpu:0.001488 message:12 mqlen:0 task:1
:01000007 cpu:0.000519 message:3 mqlen:0 task:0
:01000008 cpu:0.001077 message:5 mqlen:0 task:0
:0100000a cpu:0.000971 message:3 mqlen:0 task:0
:0100000b cpu:0.000307 message:4 mqlen:0 task:1
:0100000c cpu:0.001407 message:8 mqlen:0 task:1
:0100000d cpu:0.00033 message:3 mqlen:0 task:0
:0100000e cpu:0.000305 message:6 mqlen:0 task:0
:0100000f cpu:0.000572 message:5 mqlen:0 task:0
<CMD OK>
> curl --http0.9 'http://127.0.0.1:8000/inject/:0100000c/debug_console_inject_source.lua'
Welcome to skynet console
<CMD OK>
> curl --http0.9 'http://127.0.0.1:8000/stat'
Welcome to skynet console
:01000004 cpu:0.000989 message:16 mqlen:0 task:1 xmem:59.74 Kb (snlua cmaster)
:01000005 cpu:0.000966 message:18 mqlen:0 task:1 xmem:64.34 Kb (snlua cslave)
:01000007 cpu:0.000362 message:9 mqlen:0 task:0 xmem:44.60 Kb (snlua datacenterd)
:01000008 cpu:0.000686 message:11 mqlen:0 task:0 xmem:53.16 Kb (snlua service_mgr)
:0100000a cpu:0.001229 message:9 mqlen:0 task:0 xmem:251.01 Kb (snlua protoloader)
:0100000b cpu:0.000534 message:10 mqlen:0 task:1 xmem:58.34 Kb (snlua console)
:0100000c cpu:0.008822 message:95 mqlen:0 task:1 xmem:87.67 Kb (snlua debug_console 8000)
:0100000d cpu:0.000425 message:9 mqlen:0 task:0 xmem:48.51 Kb (snlua simpledb)
:0100000e cpu:0.000353 message:12 mqlen:0 task:0 xmem:47.07 Kb (snlua watchdog)
:0100000f cpu:0.000516 message:11 mqlen:0 task:0 xmem:53.19 Kb (snlua gate)
<CMD OK>
-- debug_console_inject_source.lua
local function getupvaluetable(u, func, unique)
unique = unique or {}
local i = 1
while true do
local name, value = debug.getupvalue(func, i)
if name == nil then
return
end
local t = type(value)
if t == "table" then
u[name] = value
elseif t == "function" then
if not unique[value] then
unique[value] = true
getupvaluetable(u, value, unique)
end
end
i=i+1
end
end
local skynet = require "skynet"
local TIMEOUT = 300 -- 3 sec
local function timeout(ti)
if ti then
ti = tonumber(ti)
if ti <= 0 then
ti = nil
end
else
ti = TIMEOUT
end
return ti
end
local function stat(ti)
local statlist = skynet.call(".launcher", "lua", "STAT", timeout(ti))
local memlist = skynet.call(".launcher", "lua", "MEM", timeout(ti))
local memkv = {}
for k,v in pairs(memlist) do
memkv[k] = v
end
for k,v in pairs(statlist) do
v.xmem=memkv[k]
end
return statlist
end
local socket = require "skynet.socket"
local u1 = {}
getupvaluetable(u1, _P.socket.socket_message[1])
for k,v in pairs(u1.socket_pool) do
if v.callback then
local u2 = {}
getupvaluetable(u2, v.callback)
for kk,vv in pairs(u2) do
if u2.COMMAND then
u2.COMMAND.stat = stat
end
end
end
end