diff --git a/Documentation/profiling.md b/Documentation/profiling.md new file mode 100644 index 000000000..7001e43b4 --- /dev/null +++ b/Documentation/profiling.md @@ -0,0 +1,24 @@ +## Profiling + +etcd exposes profiling information from the Go pprof package over HTTP. +The basic browseable interface can be found at `http://127.0.0.1:4001/debug/pprof`. + +### Heap memory profile + +``` +go tool pprof ./bin/etcd http://127.0.0.1:4001/debug/pprof/heap +``` + +### CPU profile + +``` +go tool pprof ./bin/etcd http://127.0.0.1:4001/debug/pprof/profile +``` + +### Blocked goroutine profile + +``` +go tool pprof ./bin/etcd http://127.0.0.1:4001/debug/pprof/block +``` + +For more information on using the tools see http://blog.golang.org/profiling-go-programs diff --git a/server/server.go b/server/server.go index 2b0d4a6de..4574fe0c1 100644 --- a/server/server.go +++ b/server/server.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "net/http" + "net/http/pprof" "strings" "time" @@ -62,6 +63,7 @@ func New(name string, urlStr string, bindAddr string, tlsConf *TLSConfig, tlsInf s.installV1() s.installV2() s.installMod() + s.installDebug() return s } @@ -138,6 +140,14 @@ func (s *Server) installMod() { r.PathPrefix("/mod").Handler(http.StripPrefix("/mod", mod.HttpHandler(s.url))) } +func (s *Server) installDebug() { + s.router.HandleFunc("/debug/pprof", pprof.Index) + s.router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + s.router.HandleFunc("/debug/pprof/profile", pprof.Profile) + s.router.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + s.router.HandleFunc("/debug/pprof/{name}", pprof.Index) +} + // Adds a v1 server handler to the router. func (s *Server) handleFuncV1(path string, f func(http.ResponseWriter, *http.Request, v1.Server) error) *mux.Route { return s.handleFunc(path, func(w http.ResponseWriter, req *http.Request) error {