Goでサーバ開発するときのモニタリング

このエントリーは、KLab Advent Calendar 2015の12/14の記事です。

@hhattoです。
私は主にゲームのサーバ開発や開発チームのマネイジメントに従事しています。

今回はexpvarを使ったGo製サーバのモニタリングとその周辺ツールについて書きます。

expvar

開発の初期段階やゲームのコア部分の開発をおこなってる際は、
なかなかインフラやモニタリングツールなどにまで手がまわらない事が多いのではないでしょうか?

expvarを使えば簡単にメトリクスを取得することができます。
http://hostname:port/debug/varsにアクセスすることでメトリクスを
JSONデータで取得することが可能です。

expvarの使い方等は公式ドキュメントや以下の記事が参考になります。

ゴルーチンとCPU使用率を取得するサンプルコード例は以下の通りです。

package main

import (
    "expvar"
    "net/http"
    "os"
    "runtime"
    "time"

    "github.com/shirou/gopsutil/process"
)

var PID int
var (
    svMetrics  = expvar.NewMap("sv")
    Goroutines = new(expvar.Int)
    CpuPercent = new(expvar.Float)
)

func getCpuPercent(pid int) (percent float64) {
    proc, err := process.NewProcess(int32(pid))
    if err == nil {
        percent, err = proc.CPUPercent(time.Second * 4)
        if err != nil {
            return 0.0
        }
    }
    return percent
}

func RunCollector() chan<- bool {
    fin := make(chan bool, 1)
    ticker := time.Tick(time.Second * 5)
    ticker4cpu := time.Tick(time.Second * 1)
    go func() {
        for {
            select {
            case <-fin:
                return
            case <-ticker:
                Goroutines.Set(int64(runtime.NumGoroutine()))
            case <-ticker4cpu:
                CpuPercent.Set(getCpuPercent(PID))
            }
        }
    }()
    return fin
}

func main() {
    PID = os.Getpid()
    svMetrics.Set("Goroutines", Goroutines)
    svMetrics.Set("Cpu", CpuPercent)
    _ = RunCollector()
    http.ListenAndServe(":9999", nil)
}

expvarmon

前述の通りexpvarを使用すれば簡単にメトリクスを取得することが可能になりますが、
HTTPアクセスに対してJSONデータを返すだけですので、そのままでは確認が取りにくいと思います。
それをもっと簡単に確認できれば効率があがるかもしれません。
expvarmonはターミナル上で
expvarをフェッチして表示するコマンドラインツールです。

ツールのインストールと実行例は以下の通りです。

$ go get github.com/divan/expvarmon
$ expvarmon -i=1s -ports 8091,8092,8093,9009 -vars="sv.Goroutines,sv.Cpu,mem:memstats.Alloc,duration:memstats.PauseNs,duration:memstats.PauseTotalNs"

expvarmon
指定した更新間隔でメトリクスをフェッチして見やすく表示してくれます。
ツールを起動し続けておけばサーバがダウンしたかどうかも確認可能です。
(Servicesの名前の左側に や アイコンが表示されます。)

expwebmon

expvarmonはそれ自体とても素晴らしいツールなのですが、
もう少しグラフ(チャート)等が綺麗に表示されるとテンションあがるよね、
っという単純な思考からブラウザ経由でモニタできるツールを作ってみました。

expwebmon

使い方

$ go get github.com/hhatto/expwebmon
$ expwebmon -fetchports=8091 -vars="sv.Goroutines,sv.Cpu,memstats.Alloc,memstats.NumGC,memstats.PauseTotalNs"

デフォルトでポート9999番でサーバを起動し、ブラウザ経由でメトリクスを確認することが可能です。

ここでバシッとキラキラしたUIを収めたスクリーンショットをお見せできれば良かったのですが、
なかなかうまくいきませんでした。
現状は以下のようなものになっています。

expwebmon

正直しょぼい!!今後の改善点にしたいと思います。

まとめ

expvarexpvarmon便利だよねという記事でした。

モニタリングツールはOSSプロジェクトや外部サービス等数多ありますが、
Goを使った開発時のメトリクスをサクッと確認できる手段としてexpvarmon (やexpwebmon)を
使ってみてはいかがでしょうか?

expwebmonはもう少しブラッシュアップしたかったのですが、時間切れなので今後も継続して開発してきます。
サイドプロジェクトでのツール開発はゲーム作りにも並ぶくらい楽しい時間でした。

明日の担当は、kakkun61さんです。

このブログについて

KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。

関連記事

このブログについて

KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。