mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
Merge pull request #612 from captncraig/pprof
pprof: Adding pprof middleware for profiling caddy.
This commit is contained in:
commit
63e4352db7
4 changed files with 89 additions and 0 deletions
|
@ -61,6 +61,7 @@ var directiveOrder = []directive{
|
|||
{"mime", setup.Mime},
|
||||
{"basicauth", setup.BasicAuth},
|
||||
{"internal", setup.Internal},
|
||||
{"pprof", setup.PProf},
|
||||
{"proxy", setup.Proxy},
|
||||
{"fastcgi", setup.FastCGI},
|
||||
{"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