//获取linux环境下崩溃栈(可以根据文件最后修改时间,知悉崩溃时间) //pprof memory(cpu) need graphviz //go tool pprof --pdf/web/svg http://10.105.57.151:8101/debug/pprof/heap(profile) >one.pdf package util import ( "dsbqj-admin/pkg/logger" "fmt" "log" "net/http" _ "net/http/pprof" "os" "os/exec" "syscall" ) func init() { os.MkdirAll("logs", 0660) logFile, err := os.OpenFile("logs/sysdebug.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660) if err != nil { log.Println("open sysdebug err:", err.Error()) return } // 将进程标准出错重定向至文件,进程崩溃时运行时将向该文件记录协程调用栈信息 syscall.Dup2(int(logFile.Fd()), int(os.Stderr.Fd())) log.Println("program runtime...") //监控pprof ListenPprof() } // 端口号是否正在被使用 func PortInUse(port int) bool { checkStatement := fmt.Sprintf("lsof -i:%d ", port) output, _ := exec.Command("sh", "-c", checkStatement).CombinedOutput() if len(output) > 0 { return true } return false } // 监控pprof func ListenPprof() { go func() { port := 6060 for i := 0; i < 1000; i++ { //从6060开始,找一个空闲的端口号 if PortInUse(port) { port++ } else { break } } logger.Info("start listen pprof: %d", port) err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil) if err != nil { logger.Error("pprof listen err: %s", err.Error()) } }() } // 发送警告 func SendAlarm(group string, content string) { if group == "" { return } command := fmt.Sprint("cagent_tools alarm '《指挥官》", content, "' ", group) cmd := exec.Command("/bin/bash", "-c", command) output, err := cmd.Output() if err != nil { log.Printf("Execute Shell:%s failed with error:%s", command, err.Error()) return } log.Printf("Execute Shell:%s finished with output:\n%s", command, string(output)) }