From 50fffa2973452862ff1a805956f324da1b887f36 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 26 Sep 2018 21:10:51 +0200 Subject: [PATCH 1/2] pprof: create HTTP endpoint for setting MutexProfileFraction Allows to dynamically change the MutexProfileFraction to enable and disable mutex profiling. It should be very useful for detecting deadlocks, lock contention and general concurrency problems. How to use: To enable run: curl -X POST -v 'localhost:5001/debug/pprof-mutex/?fraction=10 To disable: curl -X POST -v 'localhost:5001/debug/pprof-mutex/?fraction=0' Fraction defines which fraction of events will be profiled. Higher it is the lower performance impact but less reliable the result. To fetch the result use: go tool pprof $PATH_TO_IPFS_BIN http://localhost:5001/debug/pprof/mutex License: MIT Signed-off-by: Jakub Sztandera --- cmd/ipfs/daemon.go | 1 + core/corehttp/mutex_profile.go | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 core/corehttp/mutex_profile.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 9d2ca2269..01c111935 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -448,6 +448,7 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error corehttp.VersionOption(), defaultMux("/debug/vars"), defaultMux("/debug/pprof/"), + corehttp.MutexFractionOption("/debug/pprof-mutex/"), corehttp.MetricsScrapingOption("/debug/metrics/prometheus"), corehttp.LogOption(), } diff --git a/core/corehttp/mutex_profile.go b/core/corehttp/mutex_profile.go new file mode 100644 index 000000000..db39a7bc9 --- /dev/null +++ b/core/corehttp/mutex_profile.go @@ -0,0 +1,45 @@ +package corehttp + +import ( + "net" + "net/http" + "runtime" + "strconv" + + core "github.com/ipfs/go-ipfs/core" +) + +// MutexFractionOption allows to set runtime.SetMutexProfileFraction via HTTP +// using POST request with parameter 'fraction'. +func MutexFractionOption(path string) ServeOption { + return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + if err := r.ParseForm(); err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + + asfr := r.Form.Get("fraction") + if len(asfr) == 0 { + w.WriteHeader(http.StatusBadRequest) + return + } + + fr, err := strconv.Atoi(asfr) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + log.Infof("Setting MutexProfileFraction to %d", fr) + runtime.SetMutexProfileFraction(fr) + }) + + return mux, nil + } +} From 12746433ea5382a50e3705db6b4ef7207e8fe656 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 27 Sep 2018 03:35:10 +0200 Subject: [PATCH 2/2] test: add tess for /debug/pprof-mutex/ endpoint License: MIT Signed-off-by: Jakub Sztandera --- test/sharness/t0110-gateway.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 8c5d4982f..89901a22f 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -106,6 +106,21 @@ test_expect_success "output only has one transfer encoding header" ' test_cmp tecount_out tecount_exp ' +curl_pprofmutex() { + curl -f -X POST "http://127.0.0.1:$apiport/debug/pprof-mutex/?fraction=$1" +} + +test_expect_success "set mutex fraction for pprof (negative so it doesn't enable)" ' + curl_pprofmutex -1 +' + +test_expect_success "test failure conditions of mutex pprof endpoint" ' + test_must_fail curl_pprofmutex && + test_must_fail curl_pprofmutex that_is_string && + test_must_fail curl -f -X GET "http://127.0.0.1:$apiport/debug/pprof-mutex/?fraction=-1" +' + + test_expect_success "setup index hash" ' mkdir index && echo "

" > index/index.html &&