diff --git a/plugin/pprof/README.md b/plugin/pprof/README.md index 27d64aee7..4ff6c6e38 100644 --- a/plugin/pprof/README.md +++ b/plugin/pprof/README.md @@ -17,10 +17,16 @@ This plugin can only be used once per Server Block. ## Syntax ~~~ -pprof [ADDRESS] +pprof [ADDRESS] { + block [RATE] +} ~~~ -If not specified, ADDRESS defaults to localhost:6053. +- If not specified, **ADDRESS** defaults to localhost:6053. + +- `block` option allow to enable the `block` profiling. see [Diagnostics, chapter profiling](https://golang.org/doc/diagnostics.html). +if you need to use `block` profile, set a positive value to **RATE**. See [runtime.SetBlockProfileRate](https://golang.org/pkg/runtime/#SetBlockProfileRate). + if not specified, **RATE** default's to 1. if `block` option is not specified the `block` profiling is disabled. ## Examples @@ -42,11 +48,13 @@ Listen on an alternate address: } ~~~ -Listen on an all addresses on port 6060: +Listen on an all addresses on port 6060: and enable block profiling ~~~ txt . { - pprof :6060 + pprof :6060 { + block + } } ~~~ diff --git a/plugin/pprof/pprof.go b/plugin/pprof/pprof.go index 6cfaa5490..8367a3071 100644 --- a/plugin/pprof/pprof.go +++ b/plugin/pprof/pprof.go @@ -6,12 +6,14 @@ import ( "net" "net/http" pp "net/http/pprof" + "runtime" ) type handler struct { - addr string - ln net.Listener - mux *http.ServeMux + addr string + rateBloc int + ln net.Listener + mux *http.ServeMux } func (h *handler) Startup() error { @@ -30,6 +32,8 @@ func (h *handler) Startup() error { h.mux.HandleFunc(path+"/symbol", pp.Symbol) h.mux.HandleFunc(path+"/trace", pp.Trace) + runtime.SetBlockProfileRate(h.rateBloc) + go func() { http.Serve(h.ln, h.mux) }() diff --git a/plugin/pprof/setup.go b/plugin/pprof/setup.go index cdc346374..66c147e78 100644 --- a/plugin/pprof/setup.go +++ b/plugin/pprof/setup.go @@ -2,6 +2,7 @@ package pprof import ( "net" + "strconv" "sync" "github.com/coredns/coredns/plugin" @@ -36,15 +37,34 @@ func setup(c *caddy.Controller) error { h.addr = args[0] _, _, e := net.SplitHostPort(h.addr) if e != nil { - return e + return plugin.Error("pprof", c.Errf("%v", e)) } } + if len(args) > 1 { return plugin.Error("pprof", c.ArgErr()) } - if c.NextBlock() { - return plugin.Error("pprof", c.ArgErr()) + + for c.NextBlock() { + switch c.Val() { + case "block": + args := c.RemainingArgs() + if len(args) > 1 { + return plugin.Error("pprof", c.ArgErr()) + } + h.rateBloc = 1 + if len(args) > 0 { + t, err := strconv.Atoi(args[0]) + if err != nil { + return plugin.Error("pprof", c.Errf("property '%s' invalid integer value '%v'", "block", args[0])) + } + h.rateBloc = t + } + default: + return plugin.Error("pprof", c.Errf("unknown property '%s'", c.Val())) + } } + } pprofOnce.Do(func() { diff --git a/plugin/pprof/setup_test.go b/plugin/pprof/setup_test.go index eaa4cb37e..276229379 100644 --- a/plugin/pprof/setup_test.go +++ b/plugin/pprof/setup_test.go @@ -14,11 +14,21 @@ func TestPProf(t *testing.T) { {`pprof`, false}, {`pprof 1.2.3.4:1234`, false}, {`pprof :1234`, false}, - {`pprof {}`, true}, + {`pprof :1234 -1`, true}, + {`pprof { + }`, false}, {`pprof /foo`, true}, {`pprof { a b }`, true}, + {`pprof { block + }`, false}, + {`pprof :1234 { + block 20 + }`, false}, + {`pprof { + block 20 30 + }`, true}, {`pprof pprof`, true}, }