PageRenderTime 49ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/third_party/gofrontend/libgo/go/net/http/pprof/pprof.go

http://github.com/axw/llgo
Go | 241 lines | 132 code | 21 blank | 88 comment | 30 complexity | 78cb1b5f915fe05d616be96a1c88fd58 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. // Copyright 2010 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package pprof serves via its HTTP server runtime profiling data
  5. // in the format expected by the pprof visualization tool.
  6. // For more information about pprof, see
  7. // http://code.google.com/p/google-perftools/.
  8. //
  9. // The package is typically only imported for the side effect of
  10. // registering its HTTP handlers.
  11. // The handled paths all begin with /debug/pprof/.
  12. //
  13. // To use pprof, link this package into your program:
  14. // import _ "net/http/pprof"
  15. //
  16. // If your application is not already running an http server, you
  17. // need to start one. Add "net/http" and "log" to your imports and
  18. // the following code to your main function:
  19. //
  20. // go func() {
  21. // log.Println(http.ListenAndServe("localhost:6060", nil))
  22. // }()
  23. //
  24. // Then use the pprof tool to look at the heap profile:
  25. //
  26. // go tool pprof http://localhost:6060/debug/pprof/heap
  27. //
  28. // Or to look at a 30-second CPU profile:
  29. //
  30. // go tool pprof http://localhost:6060/debug/pprof/profile
  31. //
  32. // Or to look at the goroutine blocking profile:
  33. //
  34. // go tool pprof http://localhost:6060/debug/pprof/block
  35. //
  36. // Or to collect a 5-second execution trace:
  37. //
  38. // wget http://localhost:6060/debug/pprof/trace?seconds=5
  39. //
  40. // To view all available profiles, open http://localhost:6060/debug/pprof/
  41. // in your browser.
  42. //
  43. // For a study of the facility in action, visit
  44. //
  45. // https://blog.golang.org/2011/06/profiling-go-programs.html
  46. //
  47. package pprof
  48. import (
  49. "bufio"
  50. "bytes"
  51. "fmt"
  52. "html/template"
  53. "io"
  54. "log"
  55. "net/http"
  56. "os"
  57. "runtime"
  58. "runtime/pprof"
  59. "strconv"
  60. "strings"
  61. "time"
  62. )
  63. func init() {
  64. http.Handle("/debug/pprof/", http.HandlerFunc(Index))
  65. http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
  66. http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
  67. http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
  68. http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
  69. }
  70. // Cmdline responds with the running program's
  71. // command line, with arguments separated by NUL bytes.
  72. // The package initialization registers it as /debug/pprof/cmdline.
  73. func Cmdline(w http.ResponseWriter, r *http.Request) {
  74. w.Header().Set("Content-Type", "text/plain; charset=utf-8")
  75. fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
  76. }
  77. // Profile responds with the pprof-formatted cpu profile.
  78. // The package initialization registers it as /debug/pprof/profile.
  79. func Profile(w http.ResponseWriter, r *http.Request) {
  80. sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
  81. if sec == 0 {
  82. sec = 30
  83. }
  84. // Set Content Type assuming StartCPUProfile will work,
  85. // because if it does it starts writing.
  86. w.Header().Set("Content-Type", "application/octet-stream")
  87. if err := pprof.StartCPUProfile(w); err != nil {
  88. // StartCPUProfile failed, so no writes yet.
  89. // Can change header back to text content
  90. // and send error code.
  91. w.Header().Set("Content-Type", "text/plain; charset=utf-8")
  92. w.WriteHeader(http.StatusInternalServerError)
  93. fmt.Fprintf(w, "Could not enable CPU profiling: %s\n", err)
  94. return
  95. }
  96. time.Sleep(time.Duration(sec) * time.Second)
  97. pprof.StopCPUProfile()
  98. }
  99. // Trace responds with the execution trace in binary form.
  100. // Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified.
  101. // The package initialization registers it as /debug/pprof/trace.
  102. func Trace(w http.ResponseWriter, r *http.Request) {
  103. sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
  104. if sec == 0 {
  105. sec = 1
  106. }
  107. // Set Content Type assuming trace.Start will work,
  108. // because if it does it starts writing.
  109. w.Header().Set("Content-Type", "application/octet-stream")
  110. w.Write([]byte("tracing not yet supported with gccgo"))
  111. /*
  112. if err := trace.Start(w); err != nil {
  113. // trace.Start failed, so no writes yet.
  114. // Can change header back to text content and send error code.
  115. w.Header().Set("Content-Type", "text/plain; charset=utf-8")
  116. w.WriteHeader(http.StatusInternalServerError)
  117. fmt.Fprintf(w, "Could not enable tracing: %s\n", err)
  118. return
  119. }
  120. time.Sleep(time.Duration(sec) * time.Second)
  121. trace.Stop()
  122. */
  123. }
  124. // Symbol looks up the program counters listed in the request,
  125. // responding with a table mapping program counters to function names.
  126. // The package initialization registers it as /debug/pprof/symbol.
  127. func Symbol(w http.ResponseWriter, r *http.Request) {
  128. w.Header().Set("Content-Type", "text/plain; charset=utf-8")
  129. // We have to read the whole POST body before
  130. // writing any output. Buffer the output here.
  131. var buf bytes.Buffer
  132. // We don't know how many symbols we have, but we
  133. // do have symbol information. Pprof only cares whether
  134. // this number is 0 (no symbols available) or > 0.
  135. fmt.Fprintf(&buf, "num_symbols: 1\n")
  136. var b *bufio.Reader
  137. if r.Method == "POST" {
  138. b = bufio.NewReader(r.Body)
  139. } else {
  140. b = bufio.NewReader(strings.NewReader(r.URL.RawQuery))
  141. }
  142. for {
  143. word, err := b.ReadSlice('+')
  144. if err == nil {
  145. word = word[0 : len(word)-1] // trim +
  146. }
  147. pc, _ := strconv.ParseUint(string(word), 0, 64)
  148. if pc != 0 {
  149. f := runtime.FuncForPC(uintptr(pc))
  150. if f != nil {
  151. fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name())
  152. }
  153. }
  154. // Wait until here to check for err; the last
  155. // symbol will have an err because it doesn't end in +.
  156. if err != nil {
  157. if err != io.EOF {
  158. fmt.Fprintf(&buf, "reading request: %v\n", err)
  159. }
  160. break
  161. }
  162. }
  163. w.Write(buf.Bytes())
  164. }
  165. // Handler returns an HTTP handler that serves the named profile.
  166. func Handler(name string) http.Handler {
  167. return handler(name)
  168. }
  169. type handler string
  170. func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  171. w.Header().Set("Content-Type", "text/plain; charset=utf-8")
  172. debug, _ := strconv.Atoi(r.FormValue("debug"))
  173. p := pprof.Lookup(string(name))
  174. if p == nil {
  175. w.WriteHeader(404)
  176. fmt.Fprintf(w, "Unknown profile: %s\n", name)
  177. return
  178. }
  179. gc, _ := strconv.Atoi(r.FormValue("gc"))
  180. if name == "heap" && gc > 0 {
  181. runtime.GC()
  182. }
  183. p.WriteTo(w, debug)
  184. return
  185. }
  186. // Index responds with the pprof-formatted profile named by the request.
  187. // For example, "/debug/pprof/heap" serves the "heap" profile.
  188. // Index responds to a request for "/debug/pprof/" with an HTML page
  189. // listing the available profiles.
  190. func Index(w http.ResponseWriter, r *http.Request) {
  191. if strings.HasPrefix(r.URL.Path, "/debug/pprof/") {
  192. name := strings.TrimPrefix(r.URL.Path, "/debug/pprof/")
  193. if name != "" {
  194. handler(name).ServeHTTP(w, r)
  195. return
  196. }
  197. }
  198. profiles := pprof.Profiles()
  199. if err := indexTmpl.Execute(w, profiles); err != nil {
  200. log.Print(err)
  201. }
  202. }
  203. var indexTmpl = template.Must(template.New("index").Parse(`<html>
  204. <head>
  205. <title>/debug/pprof/</title>
  206. </head>
  207. <body>
  208. /debug/pprof/<br>
  209. <br>
  210. profiles:<br>
  211. <table>
  212. {{range .}}
  213. <tr><td align=right>{{.Count}}<td><a href="{{.Name}}?debug=1">{{.Name}}</a>
  214. {{end}}
  215. </table>
  216. <br>
  217. <a href="goroutine?debug=2">full goroutine stack dump</a><br>
  218. </body>
  219. </html>
  220. `))