状況整理
やりたいこと
- システムのアラートやチケットトラッカーの通知をSlackに集約したい。
現状
- 社内のSlackに通知できるものが少しずつ増えてきた
- 社内のSlackのメンバーも増えてきた
現状イメージ
問題
- SlackのIncoming WebHooksが増え続けて面倒だ
- 毎回Incoming WebHooksを登録するのは面倒だ
変えたいイメージ
こんな時Slackに通知が欲しい
- Datadogで特定のメトリックが閾値超えた
- サーバサイドが503吐いた
- 定期バッチでこけた
- 本番サーバにrootで入られた。 などなど、ほぼリアルタイムで検知したい。
やってみた。
API Gatewayを作り、SlackのIncoming WebHooksに流す
ついでにAPIキーを使ってアクセス制限もかけてみる。
cURLで投げてみる。
curl -H 'x-api-key:[API_GATEWAY_KEY]' --data-urlencode 'payload={"channel": "#miyasue", "username": "きちゅね", "text": "テスト。", "icon_emoji": ":kityune:"}' https://[API_GATEWAY].execute-api.ap-northeast-1.amazonaws.com/prod
届いた。
ついでにGoで飛ばしてみたい
- Goは書いた事ない。
- Goを選んだのはクロスコンパイルに強いと聞いたから。(いろんな環境から手軽にSlack通知できるんじゃない?)
- 環境構築からビルドするまでそれほど時間はかからなかった。
- 実際にWin用とMac用にコンパイルしてみたが、上手く動いた。
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
)
func main() {
if len(os.Args) != 5 {
fmt.Println("引数: 本文 ユーザ名 チャンネル名 絵文字")
os.Exit(1)
}
apiUrl := "https://[API_GATEWAY].execute-api.ap-northeast-1.amazonaws.com/"
resource := "/prod"
u, _ := url.ParseRequestURI(apiUrl)
u.Path = resource
urlStr := fmt.Sprintf("%v", u)
payload := "{'text':'" +os.Args[1]+ "', 'username':'" +os.Args[2]+ "', 'channel':'" +os.Args[3]+ "', 'icon_emoji':'" +os.Args[4]+ "'}"
data := url.Values{}
data.Set("payload", payload)
client := &http.Client{}
r, _ := http.NewRequest("POST", urlStr, bytes.NewBufferString(data.Encode()))
r.Header.Add("x-api-key", "[API_GATEWAY_KEY]")
r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, _ := client.Do(r)
defer resp.Body.Close()
contents, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("result: %s\n", contents)
}
テスト
./notice "Goからテスト" "きちゅねかわいい" "#miyasue" ":kityune:"
無事届いた。