From 754361ebf0ff831424e6749830c5e6f905c3b7c5 Mon Sep 17 00:00:00 2001 From: Yusuke Kato Date: Sat, 26 Jan 2019 16:11:44 +0900 Subject: [PATCH] [minor] add pprof feature (#23) --- cmd/ngtd/main.go | 23 ++++-- go.mod | 3 +- go.sum | 6 +- ngtd.go | 6 +- router/router.go | 12 ++- router/routes.go | 208 ++++++++++++++++++++++++++++++----------------- 6 files changed, 170 insertions(+), 88 deletions(-) diff --git a/cmd/ngtd/main.go b/cmd/ngtd/main.go index aab9fa8..878d81a 100644 --- a/cmd/ngtd/main.go +++ b/cmd/ngtd/main.go @@ -19,7 +19,6 @@ package main import ( "database/sql" "fmt" - _ "net/http/pprof" "os" "runtime" "time" @@ -34,8 +33,10 @@ import ( ) var ( - Version = "0.0.1" - Revision = "first" + // Version is ngtd version + Version = "1.1.0" + // Revision is release revision + Revision = "profilable" index string dbType string @@ -162,6 +163,15 @@ func main() { Value: 8200, Usage: "listening port", }, + cli.IntFlag{ + Name: "pprof-port, PP", + Value: 6060, + Usage: "listening pprof port", + }, + cli.BoolFlag{ + Name: "pprof pp", + Usage: "enable pprof server", + }, }), Action: func(c *cli.Context) error { if dimension > 0 { @@ -175,9 +185,10 @@ func main() { if err != nil { return err } - n.ListenAndServe(t) - - return nil + if c.Bool("pprof") { + n.ListenAndServeProfile(c.Int("pprof-port")) + } + return n.ListenAndServe(t) }, } } diff --git a/go.mod b/go.mod index e6d112a..76faf30 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,12 @@ require ( github.com/go-redis/redis v6.15.1+incompatible github.com/golang/protobuf v1.2.0 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect - github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/mux v1.6.2 github.com/kpango/glg v1.2.6 github.com/mattn/go-sqlite3 v1.10.0 github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2 github.com/yahoojapan/gongt v0.0.0-20181107111849-1c7eac1ad545 - golang.org/x/net v0.0.0-20190110200230-915654e7eabc + golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 google.golang.org/grpc v1.18.0 gopkg.in/urfave/cli.v1 v1.20.0 ) diff --git a/go.sum b/go.sum index c2b2b24..0ae511e 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,6 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -27,8 +25,8 @@ github.com/yahoojapan/gongt v0.0.0-20181107111849-1c7eac1ad545 h1:nkTAbutwixxOs5 github.com/yahoojapan/gongt v0.0.0-20181107111849-1c7eac1ad545/go.mod h1:dZTg/XQ0W91X1qZzQ36cZOU+8U5mdFRVVonBKMlMSwk= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190110200230-915654e7eabc h1:Yx9JGxI1SBhVLFjpAkWMaO1TF+xyqtHLjZpvQboJGiM= -golang.org/x/net v0.0.0-20190110200230-915654e7eabc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522 h1:Ve1ORMCxvRmSXBwJK+t3Oy+V2vRW2OetUQBq4rJIkZE= diff --git a/ngtd.go b/ngtd.go index 9973eb0..b437cd4 100644 --- a/ngtd.go +++ b/ngtd.go @@ -80,7 +80,7 @@ func NewNGTD(index string, db kvs.KVS, port int) (*NGTD, error) { return &NGTD{ sigCh: sigCh, l: l, - port: p, + port: ":" + p, }, nil } @@ -152,6 +152,10 @@ func (n *NGTD) listenAndServeGRPC() error { return nil } +func (n *NGTD) ListenAndServeProfile(port int) error { + return http.ListenAndServe(":"+strconv.Itoa(port), router.NewPprofRouter()) +} + func (n *NGTD) Stop() { n.sigCh <- syscall.SIGINT } diff --git a/router/router.go b/router/router.go index a438739..543b8cf 100644 --- a/router/router.go +++ b/router/router.go @@ -23,12 +23,22 @@ import ( "github.com/kpango/glg" ) +// NewRouter returns routed handler func NewRouter() *mux.Router { + return newRouter(routes) +} + +// NewPprofRouter returns profile handler +func NewPprofRouter() *mux.Router { + return newRouter(profiles) +} + +func newRouter(rs []Route) *mux.Router { http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 32 router := mux.NewRouter().StrictSlash(true) - for _, route := range routes { + for _, route := range rs { router. Methods(route.Method). Path(route.Pattern). diff --git a/router/routes.go b/router/routes.go index 7cc8ae6..e7bbab2 100644 --- a/router/routes.go +++ b/router/routes.go @@ -18,6 +18,7 @@ package router import ( "net/http" + "net/http/pprof" "github.com/yahoojapan/ngtd/handler" ) @@ -30,77 +31,136 @@ type Route struct { HandlerFunc http.HandlerFunc } -var routes = []Route{ - Route{ - "Index", - http.MethodGet, - "/", - handler.Index, - }, - Route{ - "Search", - http.MethodPost, - "/search", - handler.Search, - }, - Route{ - "SearchByID", - http.MethodPost, - "/searchbyid", - handler.SearchByID, - }, - Route{ - "Insert", - http.MethodPost, - "/insert", - handler.Insert, - }, - Route{ - "MultiInsert", - http.MethodPost, - "/multiinsert", - handler.MultiInsert, - }, - Route{ - "Remove", - http.MethodGet, - "/remove/{id}", - handler.Remove, - }, - Route{ - "MultiRemove", - http.MethodPost, - "/multiremove", - handler.MultiRemove, - }, - Route{ - "CreateIndex", - http.MethodGet, - "/index/create/{pool_size}", - handler.CreateIndex, - }, - Route{ - "SaveIndex", - http.MethodGet, - "/index/save", - handler.SaveIndex, - }, - Route{ - "GetErrors", - http.MethodGet, - "/errors", - handler.GetErrors, - }, - Route{ - "GetDim", - http.MethodGet, - "/dimension", - handler.GetDimension, - }, - Route{ - "GetObjects", - http.MethodPost, - "/getobjects", - handler.GetObjects, - }, -} +var ( + routes = []Route{ + Route{ + "Index", + http.MethodGet, + "/", + handler.Index, + }, + Route{ + "Search", + http.MethodPost, + "/search", + handler.Search, + }, + Route{ + "SearchByID", + http.MethodPost, + "/searchbyid", + handler.SearchByID, + }, + Route{ + "Insert", + http.MethodPost, + "/insert", + handler.Insert, + }, + Route{ + "MultiInsert", + http.MethodPost, + "/multiinsert", + handler.MultiInsert, + }, + Route{ + "Remove", + http.MethodGet, + "/remove/{id}", + handler.Remove, + }, + Route{ + "MultiRemove", + http.MethodPost, + "/multiremove", + handler.MultiRemove, + }, + Route{ + "CreateIndex", + http.MethodGet, + "/index/create/{pool_size}", + handler.CreateIndex, + }, + Route{ + "SaveIndex", + http.MethodGet, + "/index/save", + handler.SaveIndex, + }, + Route{ + "GetErrors", + http.MethodGet, + "/errors", + handler.GetErrors, + }, + Route{ + "GetDim", + http.MethodGet, + "/dimension", + handler.GetDimension, + }, + Route{ + "GetObjects", + http.MethodPost, + "/getobjects", + handler.GetObjects, + }, + } + + profiles = []Route{ + Route{ + "Debug pprof", + http.MethodGet, + "/debug/pprof/", + pprof.Index, + }, + Route{ + "Debug cmdline", + http.MethodGet, + "/debug/pprof/cmdline", + pprof.Cmdline, + }, + Route{ + "Debug profile", + http.MethodGet, + "/debug/pprof/profile", + pprof.Profile, + }, + Route{ + "Debug symbol profile", + http.MethodGet, + "/debug/pprof/symbol", + pprof.Symbol, + }, + Route{ + "Debug trace profile", + http.MethodGet, + "/debug/pprof/trace", + pprof.Trace, + }, + Route{ + "Debug heap profile", + http.MethodGet, + "/debug/pprof/heap", + pprof.Handler("heap").ServeHTTP, + }, + Route{ + "Debug goroutine profile", + http.MethodGet, + "/debug/pprof/goroutine", + pprof.Handler("goroutine").ServeHTTP, + }, + Route{ + "Debug thread profile", + http.MethodGet, + "/debug/pprof/threadcreate", + pprof.Handler("threadcreate").ServeHTTP, + }, + Route{ + "Debug block profile", + http.MethodGet, + "/debug/pprof/block", + pprof.Handler("block").ServeHTTP, + }, + } +)