40
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-09-01

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
}

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

40
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?