228 lines
5.9 KiB
Go
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
|
|
}
|