mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-12-24 13:48:04 +08:00
117 lines
2.9 KiB
Go
117 lines
2.9 KiB
Go
package plugin_debug
|
|
|
|
import (
|
|
myproc "github.com/cloudwego/goref/pkg/proc"
|
|
"github.com/go-delve/delve/pkg/config"
|
|
"github.com/go-delve/delve/service/debugger"
|
|
"io"
|
|
"m7s.live/v5"
|
|
"net/http"
|
|
"net/http/pprof"
|
|
"os"
|
|
runtimePPROF "runtime/pprof"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
var _ = m7s.InstallPlugin[DebugPlugin]()
|
|
var conf, _ = config.LoadConfig()
|
|
|
|
type DebugPlugin struct {
|
|
m7s.Plugin
|
|
ProfileDuration time.Duration `default:"10s" desc:"profile持续时间"`
|
|
Profile string `desc:"采集profile存储文件"`
|
|
ChartPeriod time.Duration `default:"1s" desc:"图表更新周期"`
|
|
Grfout string `default:"grf.out" desc:"grf输出文件"`
|
|
}
|
|
|
|
type WriteToFile struct {
|
|
header http.Header
|
|
io.Writer
|
|
}
|
|
|
|
func (w *WriteToFile) Header() http.Header {
|
|
// return w.w.Header()
|
|
return w.header
|
|
}
|
|
|
|
// func (w *WriteToFile) Write(p []byte) (int, error) {
|
|
// // w.w.Write(p)
|
|
// return w.Writer.Write(p)
|
|
// }
|
|
func (w *WriteToFile) WriteHeader(statusCode int) {
|
|
// w.w.WriteHeader(statusCode)
|
|
}
|
|
|
|
func (p *DebugPlugin) OnInit() error {
|
|
if p.Profile != "" {
|
|
go func() {
|
|
file, err := os.Create(p.Profile)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer file.Close()
|
|
p.Info("cpu profile start")
|
|
err = runtimePPROF.StartCPUProfile(file)
|
|
time.Sleep(p.ProfileDuration)
|
|
runtimePPROF.StopCPUProfile()
|
|
p.Info("cpu profile done")
|
|
}()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *DebugPlugin) Pprof_Trace(w http.ResponseWriter, r *http.Request) {
|
|
r.URL.Path = "/debug" + r.URL.Path
|
|
pprof.Trace(w, r)
|
|
}
|
|
|
|
func (p *DebugPlugin) Pprof_profile(w http.ResponseWriter, r *http.Request) {
|
|
r.URL.Path = "/debug" + r.URL.Path
|
|
pprof.Profile(w, r)
|
|
}
|
|
|
|
func (p *DebugPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path == "/pprof" {
|
|
http.Redirect(w, r, "/debug/pprof/", http.StatusFound)
|
|
return
|
|
}
|
|
r.URL.Path = "/debug" + r.URL.Path
|
|
pprof.Index(w, r)
|
|
}
|
|
|
|
func (p *DebugPlugin) Charts_(w http.ResponseWriter, r *http.Request) {
|
|
r.URL.Path = "/static" + strings.TrimPrefix(r.URL.Path, "/charts")
|
|
staticFSHandler.ServeHTTP(w, r)
|
|
}
|
|
|
|
func (p *DebugPlugin) Charts_data(w http.ResponseWriter, r *http.Request) {
|
|
dataHandler(w, r)
|
|
}
|
|
|
|
func (p *DebugPlugin) Charts_datafeed(w http.ResponseWriter, r *http.Request) {
|
|
s.dataFeedHandler(w, r)
|
|
}
|
|
|
|
func (p *DebugPlugin) Grf(w http.ResponseWriter, r *http.Request) {
|
|
dConf := debugger.Config{
|
|
AttachPid: os.Getpid(),
|
|
Backend: "default",
|
|
CoreFile: "",
|
|
DebugInfoDirectories: conf.DebugInfoDirectories,
|
|
AttachWaitFor: "",
|
|
AttachWaitForInterval: 1,
|
|
AttachWaitForDuration: 0,
|
|
}
|
|
dbg, err := debugger.New(&dConf, nil)
|
|
defer dbg.Detach(false)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if err = myproc.ObjectReference(dbg.Target(), p.Grfout); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
w.Write([]byte("ok"))
|
|
}
|