golangのパフォーマンスを見れるライブラリがないか探していて、
golang-stats-api-handlerというパッケージを見つけました。
golang-stats-api-handlerを利用してみる
まずはInstallから
$ go get -u github.com/fukata/golang-stats-api-handler
以下がnet/http
を利用して書いたコードです。
package main
import (
"github.com/fukata/golang-stats-api-handler"
"net/http"
)
func main() {
http.HandleFunc("/stats", stats_api.Handler)
http.ListenAndServe(":8000", nil)
}
localhost:8000/stats
にアクセスすると以下のように表示されます。
$ curl -i localhost:8000/stats
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Date: Thu, 14 Dec 2017 13:43:20 GMT
Content-Length: 520
{
"time": 1513259000865514903,
"go_version": "go1.8.3",
"go_os": "darwin",
"go_arch": "amd64",
"cpu_num": 4,
"goroutine_num": 4,
"gomaxprocs": 4,
"cgo_call_num": 1,
"memory_alloc": 383784,
"memory_total_alloc": 383784,
"memory_sys": 3084288,
"memory_lookups": 15,
"memory_mallocs": 5071,
"memory_frees": 140,
"memory_stack": 327680,
"heap_alloc": 383784,
"heap_sys": 1769472,
"heap_idle": 950272,
"heap_inuse": 819200,
"heap_released": 917504,
"heap_objects": 4931,
"gc_next": 4473924,
"gc_last": 0,
"gc_num": 0,
"gc_per_second": 0,
"gc_pause_per_second": 0,
"gc_pause": []
}
メモリなどの情報を取得することができました。
apiを追加するだけなのでとても簡単に利用することができます。
これだけでも十分使いやすいライブラリなのですが、
echoなどのフレームワークに組み込むとなるとHandlerがフレームワーク独自のものなのでそのままでは使えません。
echoにstatsを確認するようのapiを実装
では、echoにstats確認用apiを追加してみます。
package main
import (
"net/http"
"github.com/fukata/golang-stats-api-handler"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.GET("/hello", hello)
e.GET("/stats", stats_api.Handler)
e.Start(":8000")
}
func hello() echo.HandlerFunc {
return func(c echo.Context) error {
return c.String(http.StatusOK, "Hello World!")
}
}
このまま実行すると
$ go run main.go
# command-line-arguments
./main.go:12: cannot use stats_api.Handler (type func(http.ResponseWriter, *http.Request)) as type echo.HandlerFunc in argument to e.GET
と表示されて実行することができません。
なので以下のように書き換えてみます。
package main
import (
"log"
"net/http"
"github.com/fukata/golang-stats-api-handler"
"github.com/labstack/echo"
)
func main() {
go func() {
http.HandlerFunc("/stats", stats_api.Handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}()
e := echo.New()
e.GET("/hello", hello)
e.Start(":8000")
}
func hello() echo.HandlerFunc {
return func(c echo.Context) error {
return c.String(http.StatusOK, "Hello World!")
}
}
これで実行すると以下のように結果を取得することができます。
$ go run main.go
$ curl -i localhost:8080/stats
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Date: Thu, 14 Dec 2017 13:43:20 GMT
Content-Length: 520
{
"time": 1513259000865514903,
"go_version": "go1.8.3",
"go_os": "darwin",
"go_arch": "amd64",
"cpu_num": 4,
"goroutine_num": 4,
"gomaxprocs": 4,
"cgo_call_num": 1,
"memory_alloc": 383784,
"memory_total_alloc": 383784,
"memory_sys": 3084288,
"memory_lookups": 15,
"memory_mallocs": 5071,
"memory_frees": 140,
"memory_stack": 327680,
"heap_alloc": 383784,
"heap_sys": 1769472,
"heap_idle": 950272,
"heap_inuse": 819200,
"heap_released": 917504,
"heap_objects": 4931,
"gc_next": 4473924,
"gc_last": 0,
"gc_num": 0,
"gc_per_second": 0,
"gc_pause_per_second": 0,
"gc_pause": []
}
これでメモリなどの情報をフレームワークを利用したapiでも取得することができました。
しかし、ここでgroutine
使うのもなーって感じがするのでecho用のHandlerをライブラリ化してみました。
echo用のHandlerを実装したライブラリ
githubにHandler用のパッケージを作成しました。
まずはinstall
go get -u github.com/y-ogura/stats-handler
コードに書くと下記のようになります。
package main
import (
"net/http"
"github.com/labstack/echo"
"github.com/y-ogura/stats-handler"
)
func main() {
e := echo.New()
e.GET("/hello", hello())
e.GET("/stats", stats_handler.EchoStatsHandler)
e.Start(":8000")
}
func hello() echo.HandlerFunc {
return func(c echo.Context) error {
return c.String(http.StatusOK, "Hello World!")
}
}
コードの見た目も多少スッキリしました。
ポートも余計に使用しなくて済みました。
実行結果も問題なく取得することができます。
$ go run main.go
$ curl -i localhost:8000/stats
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Date: Thu, 14 Dec 2017 13:43:20 GMT
Content-Length: 520
{
"time": 1513259000865514903,
"go_version": "go1.8.3",
"go_os": "darwin",
"go_arch": "amd64",
"cpu_num": 4,
"goroutine_num": 4,
"gomaxprocs": 4,
"cgo_call_num": 1,
"memory_alloc": 383784,
"memory_total_alloc": 383784,
"memory_sys": 3084288,
"memory_lookups": 15,
"memory_mallocs": 5071,
"memory_frees": 140,
"memory_stack": 327680,
"heap_alloc": 383784,
"heap_sys": 1769472,
"heap_idle": 950272,
"heap_inuse": 819200,
"heap_released": 917504,
"heap_objects": 4931,
"gc_next": 4473924,
"gc_last": 0,
"gc_num": 0,
"gc_per_second": 0,
"gc_pause_per_second": 0,
"gc_pause": []
}
さいごに
こんな感じでフレームワークを利用していてもgolang-stats-api-handlerが使えるようになりました。
ちょっとしたときに確認したいときにapiを追加しておけば簡単に確認できるのでgolang-stats-api-handlerは普段から使っています。
普段はgoaで開発を行っているのでgoa用のHandlerも作る予定でいます。
まだ、パフォーマンスチェックに関しては知識不足が多いので、もっといい方法あるよって方や良いツール知ってるよって方がいましたらコメントをお待ちしています。