用go寫一個簡單的看門狗程序(WatchDog)

簡述

由於公司的一些小程序只是臨時使用一下(再也不維護更新),有的有一些bug會致使崩潰,但又不是很嚴重,崩潰了從新啓動一下就好。
因此寫了一個看門狗程序來監控程序,掛了(由於我這裏並不關心程序的其餘狀態)就直接重啓。html

參考:軟件看門狗程序小程序

代碼

package main

import (
    "fmt"
    "log"
    "os"
    "os/exec"
    "os/signal"
    "path/filepath"
    "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
    for _, arg := range args {
        cmdline += arg + " "
    }
    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("正常退出程序")
}
相關文章
相關標籤/搜索