From 06bcd7d03c31f08dc65225b6341f2bde378d25ce Mon Sep 17 00:00:00 2001 From: David Calavera Date: Fri, 25 Mar 2016 13:25:37 -0400 Subject: [PATCH] Enable http pprof connections when pprof-address is set. Add flag to specify the address where those connections listen. Signed-off-by: David Calavera --- api/http/pprof/pprof.go | 42 ++++++++++++++++++++++++++++++++++++++++ containerd/main.go | 4 ++++ containerd/main_linux.go | 5 +++++ 3 files changed, 51 insertions(+) create mode 100644 api/http/pprof/pprof.go diff --git a/api/http/pprof/pprof.go b/api/http/pprof/pprof.go new file mode 100644 index 0000000..32c173a --- /dev/null +++ b/api/http/pprof/pprof.go @@ -0,0 +1,42 @@ +package pprof + +import ( + "expvar" + "fmt" + "net/http" + "net/http/pprof" + + "github.com/Sirupsen/logrus" +) + +func Enable(address string) { + http.Handle("/", http.RedirectHandler("/debug/pprof", http.StatusMovedPermanently)) + + http.Handle("/debug/vars", http.HandlerFunc(expVars)) + http.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index)) + http.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline)) + http.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile)) + http.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol)) + http.Handle("/debug/pprof/block", pprof.Handler("block")) + http.Handle("/debug/pprof/heap", pprof.Handler("heap")) + http.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) + http.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate")) + + go http.ListenAndServe(address, nil) + logrus.Debug("pprof listening in address %s", address) +} + +// Replicated from expvar.go as not public. +func expVars(w http.ResponseWriter, r *http.Request) { + first := true + w.Header().Set("Content-Type", "application/json; charset=utf-8") + fmt.Fprintf(w, "{\n") + expvar.Do(func(kv expvar.KeyValue) { + if !first { + fmt.Fprintf(w, ",\n") + } + first = false + fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) + }) + fmt.Fprintf(w, "\n}\n") +} diff --git a/containerd/main.go b/containerd/main.go index 96960ac..ee2931b 100644 --- a/containerd/main.go +++ b/containerd/main.go @@ -55,6 +55,10 @@ var daemonFlags = []cli.Flag{ Value: &cli.StringSlice{}, Usage: "specify additional runtime args", }, + cli.StringFlag{ + Name: "pprof-address", + Usage: "http address to listen for pprof events", + }, } func main() { diff --git a/containerd/main_linux.go b/containerd/main_linux.go index 49fc790..cf5fda5 100644 --- a/containerd/main_linux.go +++ b/containerd/main_linux.go @@ -12,6 +12,7 @@ import ( "github.com/cloudfoundry/gosigar" "github.com/codegangsta/cli" "github.com/cyberdelia/go-metrics-graphite" + "github.com/docker/containerd/api/http/pprof" "github.com/docker/containerd/osutils" "github.com/docker/containerd/supervisor" "github.com/rcrowley/go-metrics" @@ -37,6 +38,10 @@ func setAppBefore(app *cli.App) { if err := debugMetrics(context.GlobalDuration("metrics-interval"), context.GlobalString("graphite-address")); err != nil { return err } + + } + if p := context.GlobalString("pprof-address"); len(p) > 0 { + pprof.Enable(p) } if err := checkLimits(); err != nil { return err