mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
Adding pprof middleware for debugging purposes
This commit is contained in:
parent
591b209024
commit
640a0ef956
4 changed files with 89 additions and 0 deletions
|
@ -61,6 +61,7 @@ var directiveOrder = []directive{
|
||||||
{"mime", setup.Mime},
|
{"mime", setup.Mime},
|
||||||
{"basicauth", setup.BasicAuth},
|
{"basicauth", setup.BasicAuth},
|
||||||
{"internal", setup.Internal},
|
{"internal", setup.Internal},
|
||||||
|
{"pprof", setup.PProf},
|
||||||
{"proxy", setup.Proxy},
|
{"proxy", setup.Proxy},
|
||||||
{"fastcgi", setup.FastCGI},
|
{"fastcgi", setup.FastCGI},
|
||||||
{"websocket", setup.WebSocket},
|
{"websocket", setup.WebSocket},
|
||||||
|
|
26
caddy/setup/pprof.go
Normal file
26
caddy/setup/pprof.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mholt/caddy/middleware"
|
||||||
|
"github.com/mholt/caddy/middleware/pprof"
|
||||||
|
)
|
||||||
|
|
||||||
|
//PProf returns a new instance of a pprof handler. It accepts no arguments or options.
|
||||||
|
func PProf(c *Controller) (middleware.Middleware, error) {
|
||||||
|
found := false
|
||||||
|
for c.Next() {
|
||||||
|
if found {
|
||||||
|
return nil, c.Err("pprof can only be specified once")
|
||||||
|
}
|
||||||
|
if len(c.RemainingArgs()) != 0 {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
if c.NextBlock() {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
return func(next middleware.Handler) middleware.Handler {
|
||||||
|
return pprof.New(next)
|
||||||
|
}, nil
|
||||||
|
}
|
28
caddy/setup/pprof_test.go
Normal file
28
caddy/setup/pprof_test.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestPProf(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string
|
||||||
|
shouldErr bool
|
||||||
|
}{
|
||||||
|
{`pprof`, false},
|
||||||
|
{`pprof {}`, true},
|
||||||
|
{`pprof /foo`, true},
|
||||||
|
{`pprof {
|
||||||
|
a b
|
||||||
|
}`, true},
|
||||||
|
{`pprof
|
||||||
|
pprof`, true},
|
||||||
|
}
|
||||||
|
for i, test := range tests {
|
||||||
|
c := NewTestController(test.input)
|
||||||
|
_, err := PProf(c)
|
||||||
|
if test.shouldErr && err == nil {
|
||||||
|
t.Errorf("Test %v: Expected error but found nil", i)
|
||||||
|
} else if !test.shouldErr && err != nil {
|
||||||
|
t.Errorf("Test %v: Expected no error but found error: %v", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
middleware/pprof/pprof.go
Normal file
34
middleware/pprof/pprof.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package pprof
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
pp "net/http/pprof"
|
||||||
|
|
||||||
|
"github.com/mholt/caddy/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Handler is a simple struct whose ServeHTTP will delegate relevant pprof endpoints to net/http/pprof
|
||||||
|
type handler struct {
|
||||||
|
mux *http.ServeMux
|
||||||
|
}
|
||||||
|
|
||||||
|
//New creates a new pprof middleware
|
||||||
|
func New(next middleware.Handler) middleware.Handler {
|
||||||
|
//pretty much copying what pprof does on init: https://golang.org/src/net/http/pprof/pprof.go#L67
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/debug/pprof/", pp.Index)
|
||||||
|
mux.HandleFunc("/debug/pprof/cmdline", pp.Cmdline)
|
||||||
|
mux.HandleFunc("/debug/pprof/profile", pp.Profile)
|
||||||
|
mux.HandleFunc("/debug/pprof/symbol", pp.Symbol)
|
||||||
|
mux.HandleFunc("/debug/pprof/trace", pp.Trace)
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
return &handler{mux}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
rec := middleware.NewResponseRecorder(w)
|
||||||
|
h.mux.ServeHTTP(rec, r)
|
||||||
|
return rec.Status(), nil
|
||||||
|
}
|
Loading…
Reference in a new issue