diff options
author | Russ Cox <rsc@golang.org> | 2011-03-25 12:50:12 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2011-03-25 12:50:12 -0400 |
commit | e857dd5d3f1e77bcbed0884324588d1b63075555 (patch) | |
tree | eeb5b0432904f0da8cd5b02087ccd4ac00b69889 | |
parent | 500effe79ebbb9b130d2ad5a86c92c2f960f2456 (diff) | |
download | go-e857dd5d3f1e77bcbed0884324588d1b63075555.tar.gz go-e857dd5d3f1e77bcbed0884324588d1b63075555.zip |
http/pprof: cpu profiling support
R=r
CC=golang-dev
https://golang.org/cl/4280060
-rw-r--r-- | src/pkg/http/pprof/pprof.go | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/src/pkg/http/pprof/pprof.go b/src/pkg/http/pprof/pprof.go index 0bac26687d..bc79e21832 100644 --- a/src/pkg/http/pprof/pprof.go +++ b/src/pkg/http/pprof/pprof.go @@ -18,6 +18,10 @@ // // pprof http://localhost:6060/debug/pprof/heap // +// Or to look at a 30-second CPU profile: +// +// pprof http://localhost:6060/debug/pprof/profile +// package pprof import ( @@ -29,10 +33,12 @@ import ( "runtime/pprof" "strconv" "strings" + "time" ) func init() { http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline)) + http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile)) http.Handle("/debug/pprof/heap", http.HandlerFunc(Heap)) http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol)) } @@ -41,22 +47,46 @@ func init() { // command line, with arguments separated by NUL bytes. // The package initialization registers it as /debug/pprof/cmdline. func Cmdline(w http.ResponseWriter, r *http.Request) { - w.Header().Set("content-type", "text/plain; charset=utf-8") + w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, strings.Join(os.Args, "\x00")) } // Heap responds with the pprof-formatted heap profile. // The package initialization registers it as /debug/pprof/heap. func Heap(w http.ResponseWriter, r *http.Request) { - w.Header().Set("content-type", "text/plain; charset=utf-8") + w.Header().Set("Content-Type", "text/plain; charset=utf-8") pprof.WriteHeapProfile(w) } +// Profile responds with the pprof-formatted cpu profile. +// The package initialization registers it as /debug/pprof/profile. +func Profile(w http.ResponseWriter, r *http.Request) { + sec, _ := strconv.Atoi64(r.FormValue("seconds")) + if sec == 0 { + sec = 30 + } + + // Set Content Type assuming StartCPUProfile will work, + // because if it does it starts writing. + w.Header().Set("Content-Type", "application/octet-stream") + if err := pprof.StartCPUProfile(w); err != nil { + // StartCPUProfile failed, so no writes yet. + // Can change header back to text content + // and send error code. + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Could not enable CPU profiling: %s\n", err) + return + } + time.Sleep(sec * 1e9) + pprof.StopCPUProfile() +} + // Symbol looks up the program counters listed in the request, // responding with a table mapping program counters to function names. // The package initialization registers it as /debug/pprof/symbol. func Symbol(w http.ResponseWriter, r *http.Request) { - w.Header().Set("content-type", "text/plain; charset=utf-8") + w.Header().Set("Content-Type", "text/plain; charset=utf-8") // We don't know how many symbols we have, but we // do have symbol information. Pprof only cares whether |