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


簡述

因為公司的一些小程序只是臨時使用一下(不再維護更新),有的有一些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("正常退出程序")
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM