ghttp_server_pprof.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright GoFrame Author(https://goframe.org). 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. defaultPProfServerName = "pprof-server"
  17. defaultPProfPattern = "/debug/pprof"
  18. )
  19. // StartPProfServer starts and runs a new server for pprof.
  20. func StartPProfServer(port int, pattern ...string) {
  21. s := GetServer(defaultPProfServerName)
  22. s.EnablePProf()
  23. s.SetPort(port)
  24. s.Run()
  25. }
  26. // EnablePProf enables PProf feature for server.
  27. func (s *Server) EnablePProf(pattern ...string) {
  28. s.Domain(defaultDomainName).EnablePProf(pattern...)
  29. }
  30. // EnablePProf enables PProf feature for server of specified domain.
  31. func (d *Domain) EnablePProf(pattern ...string) {
  32. p := defaultPProfPattern
  33. if len(pattern) > 0 && pattern[0] != "" {
  34. p = pattern[0]
  35. }
  36. up := &utilPProf{}
  37. _, _, uri, _ := d.server.parsePattern(p)
  38. uri = strings.TrimRight(uri, "/")
  39. d.Group(uri, func(group *RouterGroup) {
  40. group.ALL("/*action", up.Index)
  41. group.ALL("/cmdline", up.Cmdline)
  42. group.ALL("/profile", up.Profile)
  43. group.ALL("/symbol", up.Symbol)
  44. group.ALL("/trace", up.Trace)
  45. })
  46. }
  47. // Index shows the PProf index page.
  48. func (p *utilPProf) Index(r *Request) {
  49. profiles := runpprof.Profiles()
  50. action := r.GetString("action")
  51. data := map[string]interface{}{
  52. "uri": strings.TrimRight(r.URL.Path, "/") + "/",
  53. "profiles": profiles,
  54. }
  55. if len(action) == 0 {
  56. buffer, _ := gview.ParseContent(r.Context(), `
  57. <html>
  58. <head>
  59. <title>GoFrame PProf</title>
  60. </head>
  61. {{$uri := .uri}}
  62. <body>
  63. profiles:<br>
  64. <table>
  65. {{range .profiles}}
  66. <tr>
  67. <td align=right>{{.Count}}</td>
  68. <td><a href="{{$uri}}{{.Name}}?debug=1">{{.Name}}</a></td>
  69. <tr>
  70. {{end}}
  71. </table>
  72. <br><a href="{{$uri}}goroutine?debug=2">full goroutine stack dump</a><br>
  73. </body>
  74. </html>
  75. `, data)
  76. r.Response.Write(buffer)
  77. return
  78. }
  79. for _, p := range profiles {
  80. if p.Name() == action {
  81. p.WriteTo(r.Response.Writer, r.GetRequestInt("debug"))
  82. break
  83. }
  84. }
  85. }
  86. // Cmdline responds with the running program's
  87. // command line, with arguments separated by NUL bytes.
  88. // The package initialization registers it as /debug/pprof/cmdline.
  89. func (p *utilPProf) Cmdline(r *Request) {
  90. netpprof.Cmdline(r.Response.Writer, r.Request)
  91. }
  92. // Profile responds with the pprof-formatted cpu profile.
  93. // Profiling lasts for duration specified in seconds GET parameter, or for 30 seconds if not specified.
  94. // The package initialization registers it as /debug/pprof/profile.
  95. func (p *utilPProf) Profile(r *Request) {
  96. netpprof.Profile(r.Response.Writer, r.Request)
  97. }
  98. // Symbol looks up the program counters listed in the request,
  99. // responding with a table mapping program counters to function names.
  100. // The package initialization registers it as /debug/pprof/symbol.
  101. func (p *utilPProf) Symbol(r *Request) {
  102. netpprof.Symbol(r.Response.Writer, r.Request)
  103. }
  104. // Trace responds with the execution trace in binary form.
  105. // Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified.
  106. // The package initialization registers it as /debug/pprof/trace.
  107. func (p *utilPProf) Trace(r *Request) {
  108. netpprof.Trace(r.Response.Writer, r.Request)
  109. }