ghttp_server_pprof.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright GoFrame Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package ghttp
  7. import (
  8. netpprof "net/http/pprof"
  9. runpprof "runtime/pprof"
  10. "strings"
  11. "github.com/gogf/gf/os/gview"
  12. )
  13. // utilPProf is the PProf interface implementer.
  14. type utilPProf struct{}
  15. const (
  16. gDEFAULT_PPROF_PATTERN = "/debug/pprof"
  17. )
  18. // EnablePProf enables PProf feature for server.
  19. func (s *Server) EnablePProf(pattern ...string) {
  20. s.Domain(defaultDomainName).EnablePProf(pattern...)
  21. }
  22. // EnablePProf enables PProf feature for server of specified domain.
  23. func (d *Domain) EnablePProf(pattern ...string) {
  24. p := gDEFAULT_PPROF_PATTERN
  25. if len(pattern) > 0 && pattern[0] != "" {
  26. p = pattern[0]
  27. }
  28. up := &utilPProf{}
  29. _, _, uri, _ := d.server.parsePattern(p)
  30. uri = strings.TrimRight(uri, "/")
  31. d.Group(uri, func(group *RouterGroup) {
  32. group.ALL("/*action", up.Index)
  33. group.ALL("/cmdline", up.Cmdline)
  34. group.ALL("/profile", up.Profile)
  35. group.ALL("/symbol", up.Symbol)
  36. group.ALL("/trace", up.Trace)
  37. })
  38. }
  39. // Index shows the PProf index page.
  40. func (p *utilPProf) Index(r *Request) {
  41. profiles := runpprof.Profiles()
  42. action := r.GetString("action")
  43. data := map[string]interface{}{
  44. "uri": strings.TrimRight(r.URL.Path, "/") + "/",
  45. "profiles": profiles,
  46. }
  47. if len(action) == 0 {
  48. buffer, _ := gview.ParseContent(`
  49. <html>
  50. <head>
  51. <title>gf ghttp pprof</title>
  52. </head>
  53. {{$uri := .uri}}
  54. <body>
  55. profiles:<br>
  56. <table>
  57. {{range .profiles}}<tr><td align=right>{{.Count}}<td><a href="{{$uri}}{{.Name}}?debug=1">{{.Name}}</a>{{end}}
  58. </table>
  59. <br><a href="{{$uri}}goroutine?debug=2">full goroutine stack dump</a><br>
  60. </body>
  61. </html>
  62. `, data)
  63. r.Response.Write(buffer)
  64. return
  65. }
  66. for _, p := range profiles {
  67. if p.Name() == action {
  68. p.WriteTo(r.Response.Writer, r.GetRequestInt("debug"))
  69. break
  70. }
  71. }
  72. }
  73. // Cmdline responds with the running program's
  74. // command line, with arguments separated by NUL bytes.
  75. // The package initialization registers it as /debug/pprof/cmdline.
  76. func (p *utilPProf) Cmdline(r *Request) {
  77. netpprof.Cmdline(r.Response.Writer, r.Request)
  78. }
  79. // Profile responds with the pprof-formatted cpu profile.
  80. // Profiling lasts for duration specified in seconds GET parameter, or for 30 seconds if not specified.
  81. // The package initialization registers it as /debug/pprof/profile.
  82. func (p *utilPProf) Profile(r *Request) {
  83. netpprof.Profile(r.Response.Writer, r.Request)
  84. }
  85. // Symbol looks up the program counters listed in the request,
  86. // responding with a table mapping program counters to function names.
  87. // The package initialization registers it as /debug/pprof/symbol.
  88. func (p *utilPProf) Symbol(r *Request) {
  89. netpprof.Symbol(r.Response.Writer, r.Request)
  90. }
  91. // Trace responds with the execution trace in binary form.
  92. // Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified.
  93. // The package initialization registers it as /debug/pprof/trace.
  94. func (p *utilPProf) Trace(r *Request) {
  95. netpprof.Trace(r.Response.Writer, r.Request)
  96. }