进程守护,异常报警

This commit is contained in:
kony
2025-01-09 12:41:11 +08:00
parent 324d22c37c
commit 4facfe8aee
7 changed files with 140 additions and 27 deletions

View File

@@ -4,5 +4,5 @@ Website = "https://goodlink.kony.vip"
Icon = "theme/favicon.png"
Name = "goodlink-windows-amd64-ui"
ID = "goodlink.kony.vip"
Version = "1.14.24"
Version = "1.14.25"
Build = 0

View File

@@ -15,24 +15,21 @@ type RedisInfo struct {
}
type ConfigInfo struct {
Redis RedisInfo `bson:"redis" json:"redis"`
WorkType string `bson:"work_type" json:"work_type"`
TunKey string `bson:"tun_key" json:"tun_key"`
ConnType string `bson:"conn_type" json:"conn_type"`
LocalIP string `bson:"local_ip" json:"local_ip"`
LocalPort string `bson:"local_port" json:"local_port"`
RemoteType string `bson:"remote_type" json:"remote_type"`
RemoteIP string `bson:"remote_ip" json:"remote_ip"`
RemotePort string `bson:"remote_port" json:"remote_port"`
StunList []string `bson:"stun_list" json:"stun_list"`
Redis RedisInfo `bson:"redis" json:"redis"`
WorkType string `bson:"work_type" json:"work_type"`
TunKey string `bson:"tun_key" json:"tun_key"`
ConnType string `bson:"conn_type" json:"conn_type"`
LocalIP string `bson:"local_ip" json:"local_ip"`
LocalPort string `bson:"local_port" json:"local_port"`
RemoteType string `bson:"remote_type" json:"remote_type"`
RemoteIP string `bson:"remote_ip" json:"remote_ip"`
RemotePort string `bson:"remote_port" json:"remote_port"`
StunList []string `bson:"stun_list" json:"stun_list"`
DingTalkUrl string `bson:"ding_talk_url" json:"ding_talk_url"`
}
var configInfo ConfigInfo
func GetConfig() ConfigInfo {
return configInfo
}
func Init() error {
client := &http.Client{Timeout: 3 * time.Second}
resp, err := client.Get("https://gitee.com/konyshe/goodlink_conf/raw/master/config.json")
@@ -56,14 +53,25 @@ func Init() error {
return nil
}
func GetConfig() ConfigInfo {
if len(configInfo.StunList) == 0 {
Init()
}
return configInfo
}
func GetAddr() string {
return configInfo.Redis.Addr
return GetConfig().Redis.Addr
}
func GetPasswd() string {
return configInfo.Redis.Passwd
return GetConfig().Redis.Passwd
}
func GetID() int {
return configInfo.Redis.Id
return GetConfig().Redis.Id
}
func GetDingTalkUrl() string {
return GetConfig().DingTalkUrl
}

View File

@@ -25,11 +25,6 @@ var (
func help() {
v := flag.Bool("v", false, "查看版本信息")
/* 没有用到的参数 */
var temp_value int64
flag.Int64Var(&temp_value, "gogo-restart-delay", 1000, "自动重启的延迟时间, 单位: 毫秒")
flag.Bool("gogo-background", false, "后台执行")
flag.StringVar(&m_cli_stun_svr_addr, "stun_svr", "", "stun svr listen addr")
flag.IntVar(&m_cli_stun_svr_port, "stun_port", 3478, "stun svr listen port")
m_cli_stun_test = flag.Bool("stun_test", false, "后台执行")
@@ -45,6 +40,9 @@ func help() {
flag.IntVar(&m_cli_stun_timeout, "time_out", 30, "最大连接超时, 单位: 秒")
flag.IntVar(&m_cli_conn_type, "conn", 0, "若超过10分钟无法连接, 可尝试更换连接方式: 0: 主动; 1: 被动")
/* 没有用到的参数 */
flag.Bool("fork", false, "子进程")
flag.Parse()
if *v {

View File

@@ -3,10 +3,10 @@
package main
import (
"gogo"
"goodlink/pro"
_ "goodlink/pro"
"goodlink/stun2"
"goodlink/tools"
"log"
"net/http"
_ "net/http/pprof"
@@ -67,10 +67,11 @@ func main2() {
func main() {
help()
gogo.GuardStart(main2, func(err error) {
tools.GuardStart(main2, 500*time.Millisecond, func(err error) {
// if 0: err==nil; -1: err==255; -2: err==254; err==1: 1; err==2
if err != nil {
log.Printf(" 发现导致重启的错误: %v", err)
log.Printf(" 异常退出: %v", err)
tools.DingF("error: %v", err)
}
})
}

View File

@@ -5,7 +5,11 @@ package main
import (
_ "goodlink/pro"
"goodlink/theme"
"goodlink/tools"
"goodlink/ui2"
"log"
"os"
"time"
_ "embed"
_ "net/http/pprof"
@@ -19,7 +23,7 @@ const (
M_APP_TITLE = "GoodLink"
)
func main() {
func main2() {
myApp := app.New()
myApp.Settings().SetTheme(&theme.MyTheme{})
icon, _ := fyne.LoadResourceFromPath("./theme/favicon.png")
@@ -39,5 +43,19 @@ func main() {
myWindow.SetCloseIntercept(func() {
myWindow.Hide()
})
myWindow.ShowAndRun()
}
func main() {
help()
tools.GuardStart(main2, 500*time.Millisecond, func(err error) {
// if 0: err==nil; -1: err==255; -2: err==254; err==1: 1; err==2
if err == nil {
os.Exit(0)
}
log.Printf(" 异常退出: %v", err)
tools.DingF("error: %v", err)
})
}

31
tools/dingding.go Normal file
View File

@@ -0,0 +1,31 @@
package tools
import (
"fmt"
"goodlink/config"
"github.com/imroc/req/v3"
)
var configInfo config.ConfigInfo
type DIND_TEXT_TYPE struct {
Content string `json:"content"`
}
type DIND_MSG_TYPE struct {
MsgType string `json:"msgtype"`
Text DIND_TEXT_TYPE `json:"text"`
}
// 如果程序发生异常退出,会将异常的代码段发送到钉钉机器人,作者会针对该部分代码分析
// 这里不涉及用户隐私!!!!!!!
// 请不要往这个钉钉机器人发送垃圾信息!!!!!!!
func DingF(format string, v ...any) {
req.C().R().SetBody(&DIND_MSG_TYPE{
MsgType: "text",
Text: DIND_TEXT_TYPE{
Content: fmt.Sprintf(format, v...),
},
}).Post(config.GetDingTalkUrl())
}

57
tools/guard.go Normal file
View File

@@ -0,0 +1,57 @@
package tools
import (
"log"
"os"
"os/exec"
"strings"
"time"
)
func GuardStart(proc_handler func(), time_out time.Duration, err_handle func(err error)) {
var args []string
fork := false
ret := false
for i := 1; i < len(os.Args); i++ {
if strings.HasPrefix(os.Args[i], "--fork") {
ret = true
continue
}
args = append(args, os.Args[i])
}
if !ret {
args = append(args, "--fork")
} else {
fork = true
}
time.Sleep(time_out)
if !fork {
log.Println(" 父进程开始")
for {
cmd := exec.Command(os.Args[0], args...)
cmd.Env = os.Environ()
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
var err error
if err = cmd.Start(); err != nil {
log.Printf("failed to run command: %v\n", err)
} else if err = cmd.Wait(); err != nil {
log.Printf("failed to wait command: %v\n", err)
}
err_handle(err)
time.Sleep(time_out)
}
}
log.Println(" 子进程开始")
proc_handler()
}