2019-02-02 16:18:25 +08:00
|
|
|
// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
2018-04-17 13:54:33 +08:00
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
2019-02-02 16:18:25 +08:00
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
2018-04-17 13:54:33 +08:00
|
|
|
// pprof封装.
|
|
|
|
|
|
|
|
package ghttp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
runpprof "runtime/pprof"
|
|
|
|
netpprof "net/http/pprof"
|
2019-02-02 16:18:25 +08:00
|
|
|
"github.com/gogf/gf/g/os/gview"
|
2018-04-17 13:54:33 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// 用于pprof的对象
|
2018-05-13 14:23:14 +08:00
|
|
|
type utilPprof struct {}
|
2018-04-17 13:54:33 +08:00
|
|
|
|
2018-05-13 14:23:14 +08:00
|
|
|
func (p *utilPprof) Index(r *Request) {
|
2018-04-17 13:54:33 +08:00
|
|
|
profiles := runpprof.Profiles()
|
|
|
|
action := r.Get("action")
|
|
|
|
data := map[string]interface{}{
|
|
|
|
"uri" : strings.TrimRight(r.URL.Path, "/") + "/",
|
|
|
|
"profiles" : profiles,
|
|
|
|
}
|
|
|
|
if len(action) == 0 {
|
2018-05-13 14:23:14 +08:00
|
|
|
buffer, _ := gview.ParseContent(`
|
2018-04-17 13:54:33 +08:00
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>gf ghttp pprof</title>
|
|
|
|
</head>
|
|
|
|
{{$uri := .uri}}
|
|
|
|
<body>
|
|
|
|
profiles:<br>
|
|
|
|
<table>
|
|
|
|
{{range .profiles}}<tr><td align=right>{{.Count}}<td><a href="{{$uri}}{{.Name}}?debug=1">{{.Name}}</a>{{end}}
|
|
|
|
</table>
|
|
|
|
<br><a href="{{$uri}}goroutine?debug=2">full goroutine stack dump</a><br>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
`, data)
|
|
|
|
r.Response.Write(buffer)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for _, p := range profiles {
|
|
|
|
if p.Name() == action {
|
2018-04-30 22:14:14 +08:00
|
|
|
p.WriteTo(r.Response.Writer, r.GetRequestInt("debug"))
|
2018-04-17 13:54:33 +08:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-13 14:23:14 +08:00
|
|
|
func (p *utilPprof) Cmdline(r *Request) {
|
2019-01-24 14:03:48 +08:00
|
|
|
netpprof.Cmdline(r.Response.Writer, r.Request)
|
2018-04-17 13:54:33 +08:00
|
|
|
}
|
|
|
|
|
2018-05-13 14:23:14 +08:00
|
|
|
func (p *utilPprof) Profile(r *Request) {
|
2019-01-24 14:03:48 +08:00
|
|
|
netpprof.Profile(r.Response.Writer, r.Request)
|
2018-04-17 13:54:33 +08:00
|
|
|
}
|
|
|
|
|
2018-05-13 14:23:14 +08:00
|
|
|
func (p *utilPprof) Symbol(r *Request) {
|
2019-01-24 14:03:48 +08:00
|
|
|
netpprof.Symbol(r.Response.Writer, r.Request)
|
2018-04-17 13:54:33 +08:00
|
|
|
}
|
|
|
|
|
2018-05-13 14:23:14 +08:00
|
|
|
func (p *utilPprof) Trace(r *Request) {
|
2019-01-24 14:03:48 +08:00
|
|
|
netpprof.Trace(r.Response.Writer, r.Request)
|
2018-04-17 13:54:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 开启pprof支持
|
2018-04-17 14:08:45 +08:00
|
|
|
func (s *Server) EnablePprof(pattern...string) {
|
|
|
|
p := "/debug/pprof"
|
|
|
|
if len(pattern) > 0 {
|
|
|
|
p = pattern[0]
|
|
|
|
}
|
2018-05-13 14:23:14 +08:00
|
|
|
up := &utilPprof{}
|
2018-04-17 14:08:45 +08:00
|
|
|
_, _, uri, _ := s.parsePattern(p)
|
2018-04-17 13:54:33 +08:00
|
|
|
uri = strings.TrimRight(uri, "/")
|
|
|
|
s.BindHandler(uri + "/*action", up.Index)
|
|
|
|
s.BindHandler(uri + "/cmdline", up.Cmdline)
|
|
|
|
s.BindHandler(uri + "/profile", up.Profile)
|
|
|
|
s.BindHandler(uri + "/symbol", up.Symbol)
|
|
|
|
s.BindHandler(uri + "/trace", up.Trace)
|
|
|
|
}
|