示例#1
0
文件: main.go 项目: petertseng/p2
func main() {
	conf, err := config.LoadFromEnvironment()
	fatalize(err)
	sshConf, err := conf.ReadMap("ssh_monitor")
	fatalize(err)

	sshKeyPath, err := sshConf.ReadString("ssh_key")
	fatalize(err)
	sshUser, err := sshConf.ReadString("ssh_user")
	fatalize(err)
	sshAddr, err := sshConf.ReadString("ssh_address")
	fatalize(err)
	monitorPortStr, err := sshConf.ReadString("port")
	fatalize(err)
	if sshKeyPath == "" || sshUser == "" || sshAddr == "" || monitorPortStr == "" {
		logging.DefaultLogger.NoFields().Fatalln("Must set all of ssh_key, ssh_user, ssh_address and port")
	}
	monitorPort, err := strconv.Atoi(monitorPortStr)
	fatalize(err)

	privateKey, err := ioutil.ReadFile(sshKeyPath)
	if err != nil {
		logging.DefaultLogger.WithErrorAndFields(err, logrus.Fields{
			"key": sshKeyPath,
		}).Fatalln("Could not read SSH private key")
	}
	authSigner, err := ssh.ParsePrivateKey(privateKey)
	if err != nil {
		logging.DefaultLogger.WithErrorAndFields(err, logrus.Fields{
			"key": sshKeyPath,
		}).Fatalln("Could not parse SSH private key")
	}
	clientConf := &ssh.ClientConfig{
		User: sshUser,
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(authSigner),
		},
	}

	http.HandleFunc("/_status", func(w http.ResponseWriter, r *http.Request) {
		c, err := ssh.Dial("tcp", sshAddr, clientConf)
		if err != nil {
			http.Error(w, err.Error(), http.StatusServiceUnavailable)
			logging.DefaultLogger.WithErrorAndFields(err, logrus.Fields{
				"user":    sshUser,
				"key":     sshKeyPath,
				"address": sshAddr,
			}).Errorln("Could not connect to SSHd")
			return
		}
		defer c.Close()

		logging.DefaultLogger.NoFields().Debugln("Connected to SSHd successfully")
		_, _ = w.Write([]byte("ok"))
	})
	if err := http.ListenAndServe(fmt.Sprintf(":%d", monitorPort), nil); err != nil {
		logging.DefaultLogger.WithError(err).Fatalln("Monitor HTTP server crashed")
	}
}
示例#2
0
文件: main.go 项目: petertseng/p2
func main() {
	config, err := config.LoadFromEnvironment()
	fatalize(err)
	runitMonCfg, err := config.ReadMap("runit_monitor")
	fatalize(err)
	childDurationStr, err := config.ReadString("child_duration")
	fatalize(err)
	if childDurationStr == "" {
		childDurationStr = "10s"
	}
	childDuration, err := time.ParseDuration(childDurationStr)
	fatalize(err)
	toMonitor, err := runitMonCfg.ReadString("to_monitor")
	fatalize(err)
	runitDir, err := runitMonCfg.ReadString("runit_root")
	fatalize(err)
	if runitDir == "" {
		runitDir = runit.DefaultBuilder.RunitRoot
	}
	statusPortStr, err := runitMonCfg.ReadString("port")
	fatalize(err)
	if statusPortStr == "" {
		logging.DefaultLogger.NoFields().Fatalln("Should have assigned a port under the runit_monitor config")
	}
	statusPort, err := strconv.Atoi(statusPortStr)
	fatalize(err)

	service := &runit.Service{Name: toMonitor, Path: filepath.Join(runitDir, toMonitor)}
	http.HandleFunc("/_status",
		func(w http.ResponseWriter, r *http.Request) {
			statResult, err := runit.DefaultSV.Stat(service)
			if err != nil {
				http.Error(w, err.Error(), http.StatusServiceUnavailable)
			} else {
				statusString := fmt.Sprintf(`{"status": "%s", "time": "%s"}`, statResult.ChildStatus, statResult.ChildTime)
				if statResult.ChildTime > childDuration && statResult.ChildStatus == runit.STATUS_RUN {
					w.Header().Set("Content-Type", "application/json")
					fmt.Fprintf(w, statusString)
				} else {
					http.Error(w, statusString, http.StatusServiceUnavailable)
				}
			}
		})
	if err = http.ListenAndServe(fmt.Sprintf(":%d", statusPort), nil); err != nil {
		logging.DefaultLogger.WithError(err).Fatalln("Service crashed")
	}
}