Commit e857dd5d authored by Russ Cox's avatar Russ Cox

http/pprof: cpu profiling support

R=r
CC=golang-dev
https://golang.org/cl/4280060
parent 500effe7
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
// //
// pprof http://localhost:6060/debug/pprof/heap // 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 package pprof
import ( import (
...@@ -29,10 +33,12 @@ import ( ...@@ -29,10 +33,12 @@ import (
"runtime/pprof" "runtime/pprof"
"strconv" "strconv"
"strings" "strings"
"time"
) )
func init() { func init() {
http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline)) 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/heap", http.HandlerFunc(Heap))
http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol)) http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
} }
...@@ -41,22 +47,46 @@ func init() { ...@@ -41,22 +47,46 @@ func init() {
// command line, with arguments separated by NUL bytes. // command line, with arguments separated by NUL bytes.
// The package initialization registers it as /debug/pprof/cmdline. // The package initialization registers it as /debug/pprof/cmdline.
func Cmdline(w http.ResponseWriter, r *http.Request) { 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")) fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
} }
// Heap responds with the pprof-formatted heap profile. // Heap responds with the pprof-formatted heap profile.
// The package initialization registers it as /debug/pprof/heap. // The package initialization registers it as /debug/pprof/heap.
func Heap(w http.ResponseWriter, r *http.Request) { 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) 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, // Symbol looks up the program counters listed in the request,
// responding with a table mapping program counters to function names. // responding with a table mapping program counters to function names.
// The package initialization registers it as /debug/pprof/symbol. // The package initialization registers it as /debug/pprof/symbol.
func Symbol(w http.ResponseWriter, r *http.Request) { 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 // We don't know how many symbols we have, but we
// do have symbol information. Pprof only cares whether // do have symbol information. Pprof only cares whether
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment