// MIT License // Copyright (c) 2017 Leslie Zheng // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package echopprof import ( "net/http/pprof" "strings" "github.com/labstack/echo/v4" ) // Wrap adds several routes from package `net/http/pprof` to *echo.Echo object. func Wrap(e *echo.Echo) { WrapGroup("", e.Group("/debug/pprof")) } // Wrapper make sure we are backward compatible. var Wrapper = Wrap // WrapGroup adds several routes from package `net/http/pprof` to *echo.Group object. func WrapGroup(prefix string, g *echo.Group) { routers := []struct { Method string Path string Handler echo.HandlerFunc }{ {"GET", "", IndexHandler()}, {"GET", "/", IndexHandler()}, {"GET", "/heap", HeapHandler()}, {"GET", "/goroutine", GoroutineHandler()}, {"GET", "/block", BlockHandler()}, {"GET", "/threadcreate", ThreadCreateHandler()}, {"GET", "/cmdline", CmdlineHandler()}, {"GET", "/profile", ProfileHandler()}, {"GET", "/symbol", SymbolHandler()}, {"POST", "/symbol", SymbolHandler()}, {"GET", "/trace", TraceHandler()}, {"GET", "/mutex", MutexHandler()}, {"GET", "/allocs", AllocsHandler()}, } for _, r := range routers { switch r.Method { case "GET": g.GET(strings.TrimPrefix(r.Path, prefix), r.Handler) case "POST": g.POST(strings.TrimPrefix(r.Path, prefix), r.Handler) } } } // IndexHandler will pass the call from /debug/pprof to pprof. func IndexHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Index(ctx.Response().Writer, ctx.Request()) return nil } } // HeapHandler will pass the call from /debug/pprof/heap to pprof. func HeapHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Handler("heap").ServeHTTP(ctx.Response(), ctx.Request()) return nil } } // GoroutineHandler will pass the call from /debug/pprof/goroutine to pprof. func GoroutineHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Handler("goroutine").ServeHTTP(ctx.Response().Writer, ctx.Request()) return nil } } // BlockHandler will pass the call from /debug/pprof/block to pprof. func BlockHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Handler("block").ServeHTTP(ctx.Response().Writer, ctx.Request()) return nil } } // ThreadCreateHandler will pass the call from /debug/pprof/threadcreate to pprof. func ThreadCreateHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Handler("threadcreate").ServeHTTP(ctx.Response().Writer, ctx.Request()) return nil } } // CmdlineHandler will pass the call from /debug/pprof/cmdline to pprof. func CmdlineHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Cmdline(ctx.Response().Writer, ctx.Request()) return nil } } // ProfileHandler will pass the call from /debug/pprof/profile to pprof. func ProfileHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Profile(ctx.Response().Writer, ctx.Request()) return nil } } // SymbolHandler will pass the call from /debug/pprof/symbol to pprof. func SymbolHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Symbol(ctx.Response().Writer, ctx.Request()) return nil } } // TraceHandler will pass the call from /debug/pprof/trace to pprof. func TraceHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Trace(ctx.Response().Writer, ctx.Request()) return nil } } // MutexHandler will pass the call from /debug/pprof/mutex to pprof. func MutexHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Handler("mutex").ServeHTTP(ctx.Response().Writer, ctx.Request()) return nil } } // AllocsHandler will pass the call from /debug/pprof/allocs to pprof. func AllocsHandler() echo.HandlerFunc { return func(ctx echo.Context) error { pprof.Handler("allocs").ServeHTTP(ctx.Response().Writer, ctx.Request()) return nil } }