diff --git a/middleware/pprof/pprof.go b/middleware/pprof/pprof.go index 03f1b0f7..65f92c73 100644 --- a/middleware/pprof/pprof.go +++ b/middleware/pprof/pprof.go @@ -2,7 +2,9 @@ package pprof import ( + "html/template" "net/http/pprof" + rpprof "runtime/pprof" "strings" "github.com/kataras/iris/context" @@ -12,7 +14,6 @@ import ( // New returns a new pprof (profile, cmdline, symbol, goroutine, heap, threadcreate, debug/block) Middleware. // Note: Route MUST have the last named parameter wildcard named '{action:path}' func New() context.Handler { - indexHandler := handlerconv.FromStd(pprof.Index) cmdlineHandler := handlerconv.FromStd(pprof.Cmdline) profileHandler := handlerconv.FromStd(pprof.Profile) symbolHandler := handlerconv.FromStd(pprof.Symbol) @@ -23,25 +24,54 @@ func New() context.Handler { return func(ctx context.Context) { ctx.ContentType("text/html") - actionPathParameter := ctx.Values().GetString("action") - if len(actionPathParameter) > 1 { - if strings.Contains(actionPathParameter, "cmdline") { + action := ctx.Params().Get("action") + if action != "" { + if strings.Contains(action, "cmdline") { cmdlineHandler((ctx)) - } else if strings.Contains(actionPathParameter, "profile") { + } else if strings.Contains(action, "profile") { profileHandler(ctx) - } else if strings.Contains(actionPathParameter, "symbol") { + } else if strings.Contains(action, "symbol") { symbolHandler(ctx) - } else if strings.Contains(actionPathParameter, "goroutine") { + } else if strings.Contains(action, "goroutine") { goroutineHandler(ctx) - } else if strings.Contains(actionPathParameter, "heap") { + } else if strings.Contains(action, "heap") { heapHandler(ctx) - } else if strings.Contains(actionPathParameter, "threadcreate") { + } else if strings.Contains(action, "threadcreate") { threadcreateHandler(ctx) - } else if strings.Contains(actionPathParameter, "debug/block") { + } else if strings.Contains(action, "debug/block") { debugBlockHandler(ctx) } - } else { - indexHandler(ctx) + return + } + + profiles := rpprof.Profiles() + data := map[string]interface{}{ + "Profiles": profiles, + "Path": ctx.RequestPath(false), + } + + if err := indexTmpl.Execute(ctx, data); err != nil { + ctx.Application().Logger().Error(err) } } } + +var indexTmpl = template.Must(template.New("index").Parse(` + + /{{.Path}} + + + {{.Path}}
+
+ profiles:
+ + {{$path := .Path}} + {{range .Profiles}} +
{{.Count}}{{.Name}} + {{end}} +
+
+ full goroutine stack dump
+ + + `))