用go写一个简单的看门狗程序(WatchDog)

简述

因为公司的一些小程序只是临时使用一下(不再维护更新),有的有一些bug会导致崩溃,但又不是很严重,崩溃了重新启动一下就好。
所以写了一个看门狗程序来监控程序,挂了(因为我这里并不关心程序的其他状态)就直接重启。

参考:软件看门狗程序

代码

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("正常退出程序")
}
上一篇:如何使用watchmedo忽略以句点开头的文件?


下一篇:Python Watchdog问题 – 缺少事件