簡述
因為公司的一些小程序只是臨時使用一下(不再維護更新),有的有一些bug會導致崩潰,但又不是很嚴重,崩潰了重新啟動一下就好。
所以寫了一個看門狗程序來監控程序,掛了(因為我這里並不關心程序的其他狀態)就直接重啟。
參考:軟件看門狗程序
代碼
package main
import (
"fmt"
"log"
"os"
"os/exec"
"os/signal"
"path/filepath"
"strings"
"syscall"
)
func main() {
argc := len(os.Args)
if argc < 2 {
fmt.Println("Usage:", os.Args[0], " pragram args...")
return
}
workdir, err := os.Getwd()
if err != nil {
fmt.Println("運行錯誤", err.Error())
}
name := os.Args[1]
args := os.Args[1:]
{
if filepath.Base(name) == name {
if lp, err := exec.LookPath(name); err != nil {
log.Println("找不到待執行程序", err.Error())
return
} else {
name = lp
}
}
}
log.Println("程序工作路徑:", workdir)
var cmdline string = strings.Join(args," ")
log.Println("開始運行:", cmdline)
var cmd *exec.Cmd
//創建監聽退出chan
c := make(chan os.Signal)
//監聽指定信號 ctrl+c kill
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
go func() {
for s := range c {
switch s {
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
log.Println("信號退出", s)
err = cmd.Process.Kill()
if err != nil {
log.Println("清理程序資源:", err.Error())
}
os.Exit(0)
}
}
}()
for {
cmd = &exec.Cmd{
Path: name,
Args: args,
Dir: workdir,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
// log.Println(cmd.Args)
err = cmd.Run()
if err != nil {
log.Println("程序運行錯誤:", err.Error())
err = cmd.Process.Kill()
if err != nil {
log.Println("清理程序資源:", err.Error())
}
log.Println("開始重啟程序")
continue
}
exitcode := cmd.ProcessState.ExitCode()
if exitcode != 0 {
log.Println("程序錯誤退出:", exitcode)
log.Println("開始重啟程序")
continue
}
break
}
log.Println("正常退出程序")
}