Go
golang
batch

Goのバッチで統計を取得するAPIを用意しておくと便利

More than 3 years have passed since last update.

golangで以下のようなKillするまでずっと動くバッチがあるとします。

package main

import (
"fmt"
"sync"
"time"
)

// なんかしらの処理
func someprocess() {
somedata := []string{"a", "b", "c", "d", "e"}

var wg sync.WaitGroup
for _, s := range somedata {
wg.Add(1)
go func(val string) {
defer wg.Done()
fmt.Println(val)
}(s)
}
}

func main() {
// ずっと動き続ける
for {
someprocess()
time.Sleep(3 * time.Second)
}
}

このとき、この処理の稼働状況を知りたくなるのが人の常なので、以下のようにhttpサーバを立てて、

jsonで統計情報を取得できるようにしておくと便利です。

(統計情報の書き込みでロックが発生しますが、処理量にもよりますがほとんど問題にならないはず。)

package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"sync"
"time"
)

var metrics *Metrics

type Metrics struct {
sync.RWMutex
PID int
StartedAt time.Time
LastWorkedAt time.Time
LoopCount int
DataCount int
}

func someprocess() {
somedata := []string{"a", "b", "c", "d", "e"}

var wg sync.WaitGroup
for _, s := range somedata {
wg.Add(1)
go func(val string) {
defer wg.Done()
fmt.Println(val)

// 詳細な処理の統計を更新
metrics.Lock()
defer metrics.Unlock()
metrics.DataCount++
}(s)
}
}

func init() {
metrics = &Metrics{
PID: os.Getpid(),
StartedAt: time.Now(),
LastWorkedAt: time.Now(),
DataCount: 0,
}
}

func MetricsHandler(w http.ResponseWriter, r *http.Request) {
metrics.RLock()
defer metrics.RUnlock()
b, err := json.Marshal(metrics)
if err != nil {
http.Error(w, http.StatusText(500), 500)
}

fmt.Fprintf(w, string(b))
}

func main() {
go func() {
for {
someprocess()

// 1ループごとの統計を更新
metrics.Lock()
metrics.LoopCount++
metrics.LastWorkedAt = time.Now()
metrics.Unlock()
time.Sleep(3 * time.Second)
}
}()

// 実行状況を表示するHTTPサーバを立てる。
port := 9001
http.HandleFunc("/metrics", MetricsHandler)
fmt.Printf("Listening on %d...\n", port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
}

起動後、http://localhost:9001/metricsにアクセスすると、以下のようなjsonが返ってきます。

{

"PID": 85568,
"StartedAt": "2015-08-31T20:41:19.326943122+09:00",
"LastWorkedAt": "2015-08-31T20:41:43.350825325+09:00",
"LoopCount": 9,
"DataCount": 45
}

これを監視するとかしておくとよいのではないでしょうか。