post Image
golangでhttpを監視するscriptを書いて結果をslackにpostする

golangで簡単なscriptを書いてみる

ぐぐると、簡単な1ファイルのサンプルスクリプトは出て来るが、もうちょっと拡張性のある、ライブラリ置き場や設定ファイル置き場を分けた様な構成でscriptを書いてみる事にした。

という事で、今回はgolangを使ってhttp監視をしてみる事にする。

ディレクトリ構成

GOPATH以下の構成。基本的にGOPATH/src以下にプロジェクトを作っていく事が推奨らしい。
src以下にprojectというディレクトリを作りその下に各ディレクトリを配置。

src - project - config - secrets.go
              |        |
              |        - targets.go
              |
              - libs - slack - slack.go
              |
              - scripts - check_http.go

config : 設定ファイル置き場。secrets.goにはgit管理したくない物を入れて.gitignoreしておくと吉。

libs : slackにpostする周りのライブラリ置き場

scripts : mainの監視用script

ソースコード

各ファイルの名前と中身、ちょっとしたコメント。

config/secrets.go

slackのincomingのurlを書いておく。
人には知られるとまずい物なので、その他のファイルとは独立させておく。

package config

var (
    IncomingUrl string = "https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXX"
)

config/targets.go

テスト用に、3つドメインを用意してみた。最初の一つだけ成功して後は失敗するテスト。

package config

import (
)

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: "Google", Host: "google.com", Path: "/", Proto: "http", Domain: "google.com"},
        HttpConfig{Name: "Google", Host: "google.com", Path: "/no-such-path", Proto: "http", Domain: "google.com"},
        HttpConfig{Name: "NiseGoogle", Host: "nisegoogle.com", Path: "/", Proto: "http", Domain: "nisegoogle.com"},
    }
}

libs/slack/slack.go

引数で貰ったmsgをそのままslackにPOSTするやつ。実はslackのgo用ライブラリがあったっぽいが書いた後に気づいた。
これ。https://github.com/nlopes/slack

書いちゃったので、今回は自分のを使う。

configをimportする時には、GOPATH/src以下からのpathで読める。
pathの前に名前をつけるとエイリアスになって便利。

package slack

import (
    "log"
    "net/http"
    "net/url"
    "strings"
    "encoding/json"
    "time"

    config "project/config"
)

type CheckConfig struct {
    Http []HttpConfig `json:"http"`
}

type HttpConfig struct {
    Name   string `json:"name"`
    Host   string `json:"host"`
    Path   string `json:"path"`
    Proto  string `json:"proto"`
    Domain string `json:"domain"`
}

type Slack struct {
    Text     string `json:"text"`
    Username string `json:"username"`
}

func Post(msg string) {
    params, _ := json.Marshal(Slack{
        msg,
        "MonitoringBot",
    })

    client := &http.Client{Timeout: 5 * time.Second}

    values := url.Values{"payload": {string(params)}}
    req, err := http.NewRequest("POST", config.IncomingUrl, strings.NewReader(values.Encode()))
    if err != nil {
        log.Print(err)
        return
    }

    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

    resp, err := client.Do(req)
    if err != nil {
        log.Print(err)
        return
    }
    defer resp.Body.Close()
}

scripts/check_http.go

監視のおおもとのやつ。単純に、ターゲット持ってきて、httpチェックをするだけ。地味にリトライ入れてみた。

package main

import (
    "net/http"
    "crypto/tls"
    "time"
    "fmt"

    slack "project/libs/slack"
    config "project/config"
)

func main() {
    for _, target := range config.HttpTargets() {
        check(target)
    }
}

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 {
            slack.Post(err.Error())
            return
        }

        req.Header.Add("Host", target.Domain)
        resp, err := client.Do(req)
        if err != nil {
            slack.Post(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 != "" {
        slack.Post(errorMessage)
    }
}

slack post結果

実行してみる。

$ go run scripts/check_http.go

期待通り、pathがおかしいやつが404、ドメイン変なやつが no such hostになった。
スクリーンショット 2015-09-02 18.58.38.png

意外に簡単に書ける、go言語。


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。