c5_labsci/web/admin/autotask/base.go
2026-01-27 00:52:00 +08:00

228 lines
5.9 KiB
Go

package autotask
import (
c "ciyon/zciyon"
"fmt"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"time"
)
func funcindex() map[string]func(map[string]any) string {
return map[string]func(map[string]any) string{
"web\\admin\\autotask\\base::dayclean": dayclean,
"web\\admin\\autotask\\base::srvstats": srvstats,
}
}
func srvstats(systemrow map[string]any) string {
defer func() {
if r := recover(); r != nil {
fmt.Println("srvstats panic:", r)
c.Log.Error("AUTO", "srvstats panic:"+r.(string))
}
}()
func_succ := c.CiyVars.Func_succ
func_fail := c.CiyVars.Func_fail
func_commit := c.CiyVars.Func_commit
func_rollback := c.CiyVars.Func_rollback
func_runms := 0
if func_succ+func_fail > 0 {
func_runms = c.CiyVars.Func_runms / (func_commit + func_rollback + 1)
}
c.CiyVars.Func_succ = 0
c.CiyVars.Func_fail = 0
c.CiyVars.Func_commit = 0
c.CiyVars.Func_rollback = 0
c.CiyVars.Func_runms = 0
disk := c.Ciy_sys_getdisk("/")
disk2 := c.Ciy_sys_getdisk("/data")
disk_sysfree := disk["free"]
disk_datafree := disk2["free"]
starttime := c.Timems()
fpath := c.CiyWebDir + "/ud/_" + c.Tostr(c.Tostamp()) + ".bin"
fsize := 1024 * 1024 // 1MB
fcontent := make([]byte, fsize)
for i := 0; i < fsize; i++ {
fcontent[i] = byte(i%70 + 30)
}
f, err := os.Create(fpath)
if err != nil {
c.Log.Error("FILE", "创建临时文件失败"+fpath+":"+err.Error())
} else {
f.Write(fcontent)
f.Close()
rcontent, err := os.ReadFile(fpath)
if err != nil {
c.Log.Error("FILE", "读取临时文件失败")
} else {
for i := 0; i < fsize; i++ {
if fcontent[i] != rcontent[i] {
c.Log.Error("FILE", "写入临时文件校验失败")
break
}
}
os.Remove(fpath)
}
}
disk_ioms := c.Timems() - starttime
output := c.RunCmd("ps", "aux", "-A")
cmddb := []string{"mysql", "mysqld"}
cmdweb := []string{"nginx", "php", "WorkerMan", "mosquitto", "gitea", "/zgo"}
cpu := map[string]float64{"db": 0, "web": 0, "oth": 0}
mem := map[string]float64{"db": 0, "web": 0, "oth": 0}
for _, line := range output {
if strings.Contains(line, "COMMAND") {
continue
}
_nextspace(&line)
_nextspace(&line)
cpup := c.Tofloat(_nextspace(&line))
memp := c.Tofloat(_nextspace(&line))
_nextspace(&line) // 虚拟内存
_nextspace(&line) // 物理内存 包括共享内存
_nextspace(&line)
_nextspace(&line)
_nextspace(&line)
_nextspace(&line)
if _arrin(line, cmddb) {
cpu["db"] += cpup
mem["db"] += memp
} else if _arrin(line, cmdweb) {
cpu["web"] += cpup
mem["web"] += memp
} else {
cpu["oth"] += cpup
mem["oth"] += memp
}
}
output = c.RunCmd("free", "-m")
mem_free := 0
matches := regexp.MustCompile(`Mem:\s+(\d+)`).FindStringSubmatch(output[1])
if len(matches) > 1 {
mem_free = c.Toint(c.Tofloat(matches[1]) * (100 - cpu["db"] - cpu["web"] - cpu["oth"]) * 1024 * 1024 / 100)
}
output = c.RunCmd("sh", "-c", "netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'")
net_tcp := 0
for _, line := range output {
ls := strings.Split(line, " ")
if ls[0] == "LISTEN" {
continue
}
if len(ls) < 2 {
continue
}
net_tcp += c.Toint(ls[1])
}
starttime = c.Timems()
resp, err := http.Get("https://www.baidu.com")
if err == nil {
resp.Body.Close()
}
net_ioms := c.Timems() - starttime
dbrows, err := c.CiyDB.Getraw("show global status")
if err != nil {
c.Log.Error("FILE", "执行show global status失败")
}
dbstat := map[string]float64{}
for _, row := range dbrows {
name := c.Tostr(row["Variable_name"])
val := c.Tofloat(row["Value"])
dbstat[name] = val
}
db_keyhit := dbstat["Handler_read_key"] / (dbstat["Com_select"] + 1) * 100
db_dbhit := dbstat["Innodb_buffer_pool_reads"] / (dbstat["Innodb_buffer_pool_read_requests"] + 1) * 100
db_tmptable := dbstat["Created_tmp_disk_tables"] / (dbstat["Created_tmp_tables"] + 1) * 100
updata := map[string]any{}
updata["func_succ"] = func_succ
updata["func_fail"] = func_fail
updata["func_commit"] = func_commit
updata["func_rollback"] = func_rollback
updata["func_runms"] = func_runms
updata["disk_sysfree"] = disk_sysfree
updata["disk_datafree"] = disk_datafree
updata["disk_ioms"] = disk_ioms
updata["cpu_free"] = 100 - cpu["db"] - cpu["web"] - cpu["oth"]
updata["cpu_db"] = cpu["db"]
updata["cpu_web"] = cpu["web"]
updata["cpu_oth"] = cpu["oth"]
updata["mem_free"] = mem_free
updata["mem_db"] = mem["db"]
updata["mem_web"] = mem["web"]
updata["mem_oth"] = mem["oth"]
updata["net_tcp"] = net_tcp
updata["net_ioms"] = net_ioms
updata["db_query"] = dbstat["Questions"]
updata["db_commit"] = dbstat["Com_commit"]
updata["db_rollback"] = dbstat["Com_rollback"]
updata["db_keyhit"] = db_keyhit
updata["db_dbhit"] = db_dbhit
updata["db_tmptable"] = db_tmptable
updata["db_lock"] = dbstat["Innodb_row_lock_current_waits"]
updata["addtimes"] = c.Tostamp()
csql := c.NewCiySQL("zc_stats")
c.CiyDB.Insert(csql, updata)
retmsg := "succ: " + c.Tostr(func_succ)
if func_rollback > 0 {
retmsg += ", rollback: " + c.Tostr(func_rollback)
}
return retmsg
}
func dayclean(systemrow map[string]any) string {
maxAge := 3 * 24 * time.Hour
cnt := 0
errcnt := 0
filepath.Walk(c.CiyWebDir+"/ud/tmp", func(path string, info os.FileInfo, err error) error {
if err != nil {
_tasklog(systemrow, "出现错误:"+err.Error())
return err
}
if info.IsDir() {
return nil
}
if time.Since(info.ModTime()) > maxAge {
err := os.Remove(path)
cnt++
if err != nil {
errcnt++
fmt.Printf("failed to delete file: %s\n", err)
}
}
return nil
})
retmsg := "clean: " + c.Tostr(cnt)
if errcnt > 0 {
retmsg += ", err: " + c.Tostr(errcnt)
}
return retmsg
}
func _nextspace(line *string) string {
ind := strings.Index(*line, " ")
if ind == -1 {
*line = ""
return *line
}
va := (*line)[:ind]
*line = (*line)[ind:]
*line = strings.TrimSpace(*line)
return va
}
func _arrin(cmd string, arr []string) bool {
for _, v := range arr {
if strings.Contains(cmd, v) {
return true
}
}
return false
}