aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2011-03-25 12:50:12 -0400
committerRuss Cox <rsc@golang.org>2011-03-25 12:50:12 -0400
commite857dd5d3f1e77bcbed0884324588d1b63075555 (patch)
treeeeb5b0432904f0da8cd5b02087ccd4ac00b69889
parent500effe79ebbb9b130d2ad5a86c92c2f960f2456 (diff)
downloadgo-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.go36
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