diff --git a/server/http_pprof.go b/server/http_pprof.go index d12a4c80..58e79a08 100644 --- a/server/http_pprof.go +++ b/server/http_pprof.go @@ -5,49 +5,26 @@ package main import ( - "fmt" "net/http" + "net/http/pprof" "path" - "runtime/pprof" - "strings" "github.com/tinode/chat/server/logs" ) -var pprofHttpRoot string - // Expose debug profiling at the given URL path. func servePprof(mux *http.ServeMux, serveAt string) { if serveAt == "" || serveAt == "-" { return } - pprofHttpRoot = path.Clean("/"+serveAt) + "/" - mux.HandleFunc(pprofHttpRoot, profileHandler) + pprofRoot := path.Clean("/"+serveAt) + "/" - logs.Info.Printf("pprof: profiling info exposed at '%s'", pprofHttpRoot) -} - -func profileHandler(wrt http.ResponseWriter, req *http.Request) { - wrt.Header().Set("X-Content-Type-Options", "nosniff") - wrt.Header().Set("Content-Type", "text/plain; charset=utf-8") - - profileName := strings.TrimPrefix(req.URL.Path, pprofHttpRoot) - - profile := pprof.Lookup(profileName) - if profile == nil { - servePprofError(wrt, http.StatusNotFound, "Unknown profile '"+profileName+"'") - return - } - - // Respond with the requested profile. - profile.WriteTo(wrt, 2) -} - -func servePprofError(wrt http.ResponseWriter, status int, txt string) { - wrt.Header().Set("Content-Type", "text/plain; charset=utf-8") - wrt.Header().Set("X-Go-Pprof", "1") - wrt.Header().Del("Content-Disposition") - wrt.WriteHeader(status) - fmt.Fprintln(wrt, txt) + mux.HandleFunc(pprofRoot, pprof.Index) + mux.HandleFunc(path.Join(pprofRoot, "cmdline"), pprof.Cmdline) + mux.HandleFunc(path.Join(pprofRoot, "profile"), pprof.Profile) + mux.HandleFunc(path.Join(pprofRoot, "symbol"), pprof.Symbol) + mux.HandleFunc(path.Join(pprofRoot, "trace"), pprof.Trace) + + logs.Info.Printf("pprof: profiling info exposed at '%s'", pprofRoot) } diff --git a/server/main.go b/server/main.go index 50002d37..b9e5e907 100644 --- a/server/main.go +++ b/server/main.go @@ -17,7 +17,6 @@ import ( "net/http" "os" "runtime" - "runtime/pprof" "strings" "time" @@ -285,7 +284,6 @@ func main() { expvarPath := flag.String("expvar", "", "Override the URL path where runtime stats are exposed. Use '-' to disable.") serverStatusPath := flag.String("server_status", "", "Override the URL path where the server's internal status is displayed. Use '-' to disable.") - pprofFile := flag.String("pprof", "", "File name to save profiling info to. Disabled if not set.") pprofUrl := flag.String("pprof_url", "", "Debugging only! URL path for exposing profiling info. Disabled if not set.") flag.Parse() @@ -355,28 +353,6 @@ func main() { // Cluster won't be started here yet. workerId := clusterInit(config.Cluster, clusterSelf) - if *pprofFile != "" { - *pprofFile = toAbsolutePath(curwd, *pprofFile) - - cpuf, err := os.Create(*pprofFile + ".cpu") - if err != nil { - logs.Err.Fatal("Failed to create CPU pprof file: ", err) - } - defer cpuf.Close() - - memf, err := os.Create(*pprofFile + ".mem") - if err != nil { - logs.Err.Fatal("Failed to create Mem pprof file: ", err) - } - defer memf.Close() - - pprof.StartCPUProfile(cpuf) - defer pprof.StopCPUProfile() - defer pprof.WriteHeapProfile(memf) - - logs.Info.Printf("Profiling info saved to '%s.(cpu|mem)'", *pprofFile) - } - err = store.Store.Open(workerId, config.Store) if err != nil { logs.Err.Fatal("Failed to connect to DB: ", err)