1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-26 01:24:05 +08:00

opt procstat

This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-05-24 14:22:39 +08:00
parent b1cfdccc28
commit ec40e9d9eb
3 changed files with 83 additions and 42 deletions

View File

@ -1,6 +1,7 @@
package cli
import (
"os"
"strings"
"time"
@ -13,43 +14,51 @@ import (
)
type procstat struct {
user int
sys int
idle int
io int
total int
free int
available int
rx int
tx int
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) {
m.Option(ice.MSG_USERROLE, aaa.ROOT)
if ls := kit.Split(m.Cmdx(nfs.CAT, kit.Format("/proc/%d/stat", os.Getpid())), " ()"); 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 = procstat{
user: kit.Int(ls[1]),
sys: kit.Int(ls[3]),
idle: kit.Int(ls[4]),
io: kit.Int(ls[5]),
}
stat.user = kit.Int64(ls[1])
stat.sys = kit.Int64(ls[3])
stat.idle = 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.Int(ls[1]) * 1024
stat.total = kit.Int64(ls[1]) * 1024
case "MemFree":
stat.free = kit.Int(ls[1]) * 1024
case "MemAvailable":
stat.available = kit.Int(ls[1]) * 1024
stat.free = kit.Int64(ls[1]) * 1024
}
}
for _, line := range strings.Split(strings.TrimSpace(m.Cmdx(nfs.CAT, "/proc/net/dev")), lex.NL)[2:] {
ls := kit.Split(line, ": ")
if ls[0] == "eth0" {
stat.rx = kit.Int(ls[1])
stat.tx = kit.Int(ls[9])
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
@ -58,29 +67,23 @@ func newprocstat(m *ice.Message) (stat procstat) {
func init() {
var last procstat
Index.MergeCommands(ice.Commands{
"procstat": {Name: "procstat id auto page insert", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
aaa.White(m, "/proc/net/dev")
aaa.White(m, "/proc/meminfo")
aaa.White(m, "/proc/stat")
last = newprocstat(m)
}},
"procstat": {Name: "procstat id list page", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { last = newprocstat(m) }},
mdb.INSERT: {Name: "insert", Hand: func(m *ice.Message, arg ...string) {
stat := newprocstat(m)
total := stat.user - last.user + stat.sys - last.sys + stat.idle - last.idle + stat.io - last.io
total := stat.user - last.user + stat.sys - last.sys + stat.idle - last.idle
m.Cmd(mdb.INSERT, m.PrefixKey(), "", mdb.LIST,
"user", (stat.user-last.user)*1000/total, "sys", (stat.sys-last.sys)*1000/total,
"idle", (stat.idle-last.idle)*1000/total, "io", (stat.io-stat.io)*1000/total,
"free", stat.free*1000/stat.total, "available", stat.available*1000/stat.total,
"rx", (stat.rx-last.rx)*1000/10000000, "tx", (stat.tx-last.tx)*1000/10000000,
"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,user,sys,idle,io,free,available,rx,tx")), Hand: func(m *ice.Message, arg ...string) {
m.OptionDefault(mdb.CACHE_LIMIT, "1000")
}, 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, "300")
mdb.PageListSelect(m, arg...)
m.SortInt(mdb.ID).Display("/plugin/story/trend.js", ice.VIEW, "折线图", "min", "0", "max", "1000", mdb.FIELD, "user,sys,idle,free,available,tx,rx", COLOR, "red,yellow,green,blue,cyan,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("time,user,sys,idle,free,available,tx,rx"), "cursor", "0")
m.SortInt(mdb.ID).Display("/plugin/story/trend.js", ice.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")
}},
})
}

View File

@ -3,6 +3,7 @@ package tcp
import (
"net"
"path"
"strconv"
"strings"
ice "shylinux.com/x/icebergs"
@ -41,13 +42,49 @@ const PORT = "port"
func init() {
Index.MergeCommands(ice.Commands{
PORT: {Name: "port port path auto", Help: "端口", Actions: ice.MergeActions(ice.Actions{
PORT: {Name: "port port path auto socket", Help: "端口", Actions: ice.MergeActions(ice.Actions{
CURRENT: {Hand: func(m *ice.Message, arg ...string) { m.Echo(mdb.Config(m, CURRENT)) }},
aaa.RIGHT: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_port_right(m, arg...)) }},
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
m.Assert(m.Option(PORT) != "")
nfs.Trash(m, path.Join(ice.USR_LOCAL_DAEMON, m.Option(PORT)))
}},
"socket": {Hand: func(m *ice.Message, arg ...string) {
parse := func(str string) int64 {
port, _ := strconv.ParseInt(str, 16, 32)
return port
}
trans := func(str string) string {
switch str {
case "0A":
return "LISTEN"
case "01":
return "ESTABLISHED"
case "06":
return "TIME_WAIT"
default:
return str
}
}
stats := map[string]int{}
m.Spawn().Split(m.Cmdx(nfs.CAT, "/proc/net/tcp")).Table(func(value ice.Maps) {
stats[trans(value["st"])]++
m.Push("status", trans(value["st"]))
ls := kit.Split(value["local_address"], ":")
m.Push("local", kit.Format("%d.%d.%d.%d:%d", parse(ls[0][6:8]), parse(ls[0][4:6]), parse(ls[0][2:4]), parse(ls[0][:2]), parse(ls[1])))
ls = kit.Split(value["rem_address"], ":")
m.Push("remote", kit.Format("%d.%d.%d.%d:%d", parse(ls[0][6:8]), parse(ls[0][4:6]), parse(ls[0][2:4]), parse(ls[0][:2]), parse(ls[1])))
})
m.Spawn().Split(m.Cmdx(nfs.CAT, "/proc/net/tcp6")).Table(func(value ice.Maps) {
stats[trans(value["st"])]++
m.Push("status", trans(value["st"]))
ls := kit.Split(value["local_address"], ":")
m.Push("local", kit.Format("%d.%d.%d.%d:%d", parse(ls[0][30:32]), parse(ls[0][28:30]), parse(ls[0][26:28]), parse(ls[0][24:26]), parse(ls[1])))
ls = kit.Split(value["remote_address"], ":")
m.Push("remote", kit.Format("%d.%d.%d.%d:%d", parse(ls[0][30:32]), parse(ls[0][28:30]), parse(ls[0][26:28]), parse(ls[0][24:26]), parse(ls[1])))
})
m.Sort("status,local").StatusTimeCount(stats)
}},
}, mdb.HashAction(BEGIN, 10000, CURRENT, 10000, END, 20000)), Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 0 {
m.Cmdy(nfs.DIR, arg[1:], kit.Dict(nfs.DIR_ROOT, path.Join(ice.USR_LOCAL_DAEMON, arg[0])))

View File

@ -53,6 +53,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
} else {
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, nfs.DF)[0])
}
// kit.For(r.Header, func(k string, v []string) { m.Debug("what %v %v", k, v) })
kit.If(path.Join(r.URL.Path) == nfs.PS, func() { r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, "main")) })
if m.Logs(r.Header.Get(ice.MSG_USERIP), r.Method, r.URL.String()); r.Method == http.MethodGet {
if msg := m.Spawn(w, r).Options(ice.MSG_USERUA, r.UserAgent()); path.Join(r.URL.Path) == nfs.PS {