kazu22002の技術覚書

PHPer, Golang, AWS エンジニアの日々

golangでweb死活監視

webの死活監視が必要になったので、lambdaでどう作るか知り合いに相談したらgolangで作ったとのことで調べてやってみました。

通知はslackへ通知するようにします。

web監視

参考

qiita.com

var (
    IncomingUrl string = "https://hooks.slack.com/services/xxx" // slack webhook url
)

type HttpConfigSlice struct {
    Http []HttpConfig
}

type HttpConfig struct {
    Name string
    Host string
    Path string
    Proto string
    Domain string
}

func HttpTargets() []HttpConfig {
    return []HttpConfig{
        HttpConfig{Name: "example", Host: "example.com", Path: "/", Proto: "https", Domain: "example.com"},
    }
}
func check(target config.HttpConfig) {
    errorNum := 0
    checkNum := 0
    fatalNum := 2
    errorMessage := ""

    for checkNum < fatalNum {
        checkNum += 1
        targetPath := target.Proto + "://" + target.Host + target.Path
        tr := &http.Transport{
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
        }
        client := &http.Client{Timeout: 5 * time.Second, Transport: tr}
        req, err := http.NewRequest("GET", targetPath, nil)
        if err != nil {
            notification(err.Error())
            return
        }

        req.Header.Add("Host", target.Domain)
        resp, err := client.Do(req)
        if err != nil {
            notification(err.Error())
            return
        }

        if resp.StatusCode != 200 {
            errorNum += 1
            if (errorNum >= fatalNum) {
                errorMessage += targetPath + " [" + target.Name + "] " + "returns " + fmt.Sprint(resp.StatusCode) + "\n"
            }
        } else {
            break
        }

        defer resp.Body.Close()
    }

    if errorMessage != "" {
        notification(errorMessage)
    }
}

通知

github.com

func notification( errorMessage string){
    attachment := slack.Attachment{
        Color:         "danger",
        Text:          "<!channel> " + errorMessage,
        Footer:        "slack lambda api",
        Ts:            json.Number(strconv.FormatInt(time.Now().Unix(), 10)),
    }
    msg := slack.WebhookMessage{
        Attachments: []slack.Attachment{attachment},
    }

    err := slack.PostWebhook(config.IncomingUrl, &msg)
    if err != nil {
        fmt.Println(err)
    }
}

まとめ

死活監視はサービスに必要ですね。

あとgolangは便利やなー。