1
0
forked from x/icebergs
icebergs/base/cli/procstat.go
2023-09-19 21:35:37 +08:00

98 lines
3.7 KiB
Go

package cli
import (
"runtime"
"strings"
"time"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
)
type procstat struct {
utime int64
stime int64
vmsize int64
vmrss int64
user int64
sys int64
idle int64
total int64
free int64
rx int64
tx int64
established int64
time_wait int64
}
func newprocstat(m *ice.Message) (stat procstat) {
if runtime.GOOS != LINUX {
return
}
m.Option(ice.MSG_USERROLE, aaa.ROOT)
if ls := kit.Split(m.Cmdx(nfs.CAT, "/proc/self/stat"), " ()"); len(ls) > 0 {
stat = procstat{utime: kit.Int64(ls[13]), stime: kit.Int64(ls[14]), vmsize: kit.Int64(ls[22]), vmrss: kit.Int64(ls[23]) * 4096}
}
if ls := kit.Split(kit.Select("", strings.Split(m.Cmdx(nfs.CAT, "/proc/stat"), lex.NL), 1)); len(ls) > 0 {
stat.user, stat.sys, stat.idle = kit.Int64(ls[1]), kit.Int64(ls[3]), kit.Int64(ls[4])
}
for _, line := range strings.Split(strings.TrimSpace(m.Cmdx(nfs.CAT, "/proc/meminfo")), lex.NL) {
switch ls := kit.Split(line, ": "); ls[0] {
case "MemTotal":
stat.total = kit.Int64(ls[1]) * 1024
case "MemFree":
stat.free = kit.Int64(ls[1]) * 1024
}
}
for _, line := range strings.Split(strings.TrimSpace(m.Cmdx(nfs.CAT, "/proc/net/dev")), lex.NL)[2:] {
if ls := kit.Split(line, ": "); ls[0] != "lo" {
stat.rx += kit.Int64(ls[1])
stat.tx += kit.Int64(ls[9])
}
}
for _, line := range strings.Split(strings.TrimSpace(m.Cmdx(nfs.CAT, "/proc/net/tcp")), lex.NL)[1:] {
switch ls := kit.Split(line, ": "); ls[5] {
case "01":
stat.established++
case "06":
stat.time_wait++
}
}
return
}
func init() {
var last procstat
Index.MergeCommands(ice.Commands{
PROCSTAT: {Name: "procstat id list page start", Help: "进程统计", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { last = newprocstat(m) }},
START: {Name: "start interval*=10s least*=360 limit*=720", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(gdb.TIMER, mdb.CREATE, mdb.NAME, m.CommandKey(), gdb.DELAY, "1s", m.OptionSimple(gdb.INTERVAL), mdb.COUNT, "-1", ice.CMD, "cli.procstat insert")
mdb.Config(m, mdb.LEAST, m.Option(mdb.LEAST))
mdb.Config(m, mdb.LIMIT, m.Option(mdb.LIMIT))
}},
mdb.INSERT: {Hand: func(m *ice.Message, arg ...string) {
stat := newprocstat(m)
total := stat.user - last.user + stat.sys - last.sys + stat.idle - last.idle
m.Cmd(mdb.INSERT, m.PrefixKey(), "", mdb.LIST,
"utime", (stat.utime-last.utime+stat.stime-last.stime)*1000/total, "vmrss", stat.vmrss*1000/stat.total,
"user", (stat.user-last.user+stat.sys-last.sys)*1000/total, "idle", (stat.idle-last.idle)*1000/total, "free", stat.free*1000/stat.total,
"rx", (stat.rx-last.rx)*1000/20000000, "tx", (stat.tx-last.tx)*1000/20000000, "established", stat.established, "time_wait", stat.time_wait,
)
last = stat
}},
}, mdb.PageListAction(mdb.FIELD, "time,id,utime,vmrss,user,idle,free,rx,tx,established,time_wait")), Hand: func(m *ice.Message, arg ...string) {
m.OptionDefault(mdb.CACHE_LIMIT, mdb.Config(m, mdb.LEAST))
if mdb.PageListSelect(m, arg...); (len(arg) == 0 || arg[0] == "") && m.Length() > 0 {
m.SortInt(mdb.ID).Display("/plugin/story/trend.js", "view", "折线图", "min", "0", "max", "1000", COLOR, "yellow,cyan,red,green,blue,purple,purple")
m.Status("from", m.Append(mdb.TIME), "span", kit.FmtDuration(time.Duration(kit.Time(m.Time())-kit.Time(m.Append(mdb.TIME)))), m.AppendSimple(mdb.Config(m, mdb.FIELD)), "cursor", "0")
}
}},
})
}