pprof_on.go (1560B)
1 //go:build debug || debugenv 2 // +build debug debugenv 3 4 package debug 5 6 import ( 7 "net/http" 8 "net/http/pprof" 9 "strings" 10 ) 11 12 // ServePprof will start an HTTP server serving /debug/pprof only if debug enabled. 13 func ServePprof(addr string) error { 14 if !DEBUG { 15 // debug disabled in env 16 return nil 17 } 18 handler := WithPprof(nil) 19 return http.ListenAndServe(addr, handler) 20 } 21 22 // WithPprof will add /debug/pprof handling (provided by "net/http/pprof") only if debug enabled. 23 func WithPprof(handler http.Handler) http.Handler { 24 if !DEBUG { 25 // debug disabled in env 26 return handler 27 } 28 29 // Default serve mux is setup with pprof 30 pprofmux := http.DefaultServeMux 31 32 if pprofmux == nil { 33 // Someone nil'ed the default mux 34 pprofmux = &http.ServeMux{} 35 pprofmux.HandleFunc("/debug/pprof/", pprof.Index) 36 pprofmux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) 37 pprofmux.HandleFunc("/debug/pprof/profile", pprof.Profile) 38 pprofmux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) 39 pprofmux.HandleFunc("/debug/pprof/trace", pprof.Trace) 40 } 41 42 if handler == nil { 43 // Ensure handler is non-nil 44 handler = http.NotFoundHandler() 45 } 46 47 // Debug enabled, return wrapped handler func 48 return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { 49 const prefix = "/debug/pprof" 50 51 // /debug/pprof(/.*)? -> pass to pprofmux 52 if strings.HasPrefix(r.URL.Path, prefix) { 53 path := r.URL.Path[len(prefix):] 54 if path == "" || path[0] == '/' { 55 pprofmux.ServeHTTP(rw, r) 56 return 57 } 58 } 59 60 // .* -> pass to handler 61 handler.ServeHTTP(rw, r) 62 }) 63 }