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