Skip to content

Commit

Permalink
(PROFILING): Add config support for setting runtime.SetMutexProfileFr…
Browse files Browse the repository at this point in the history
…action() value (thrasher-corp#432)

* Added config option for SetMutexProfileFraction() to profiler increased test coverage and made tests runnable standalone

* Removed duplicate host and no longer const

* Added pprof endpoint to log
  • Loading branch information
xtda authored Jan 30, 2020
1 parent 5746fbb commit bc0c32d
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 7 deletions.
9 changes: 5 additions & 4 deletions config/config_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ type Config struct {
Database database.Config `json:"database"`
Logging log.Config `json:"logging"`
ConnectionMonitor ConnectionMonitorConfig `json:"connectionMonitor"`
Profiler ProfilerConfig `json:"profiler"`
Profiler Profiler `json:"profiler"`
NTPClient NTPClientConfig `json:"ntpclient"`
GCTScript gctscript.Config `json:"gctscript"`
Currency CurrencyConfig `json:"currencyConfig"`
Expand Down Expand Up @@ -154,9 +154,10 @@ type ExchangeConfig struct {
WebsocketURL *string `json:"websocketUrl,omitempty"`
}

// ProfilerConfig defines the profiler configuration to enable pprof
type ProfilerConfig struct {
Enabled bool `json:"enabled"`
// Profiler defines the profiler configuration to enable pprof
type Profiler struct {
Enabled bool `json:"enabled"`
MutexProfileFraction int `json:"mutex_profile_fraction"`
}

// NTPClientConfig defines a network time protocol configuration to allow for
Expand Down
3 changes: 2 additions & 1 deletion config_example.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
"checkInterval": 1000000000
},
"profiler": {
"enabled": false
"enabled": false,
"mutex_profile_fraction": 0
},
"ntpclient": {
"enabled": 0,
Expand Down
6 changes: 5 additions & 1 deletion engine/restful_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"net/http"
_ "net/http/pprof" // nolint: gosec
"runtime"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -85,8 +86,11 @@ func newRouter(isREST bool) *mux.Router {
}

if Bot.Config.Profiler.Enabled {
if Bot.Config.Profiler.MutexProfileFraction > 0 {
runtime.SetMutexProfileFraction(Bot.Config.Profiler.MutexProfileFraction)
}
log.Debugf(log.RESTSys,
"HTTP Go performance profiler (pprof) endpoint enabled: http://%s:%d/debug\n",
"HTTP Go performance profiler (pprof) endpoint enabled: http://%s:%d/debug/pprof\n",
common.ExtractHost(listenAddr),
common.ExtractPort(listenAddr))
router.PathPrefix("/debug").Handler(http.DefaultServeMux)
Expand Down
49 changes: 49 additions & 0 deletions engine/restful_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"net/http/httptest"
"reflect"
"runtime"
"testing"

"github.com/thrasher-corp/gocryptotrader/config"
Expand Down Expand Up @@ -53,6 +54,10 @@ func TestConfigAllJsonResponse(t *testing.T) {
}

func TestInvalidHostRequest(t *testing.T) {
Bot = &Engine{
Config: loadConfig(t),
}

req, err := http.NewRequest(http.MethodGet, "/config/all", nil)
if err != nil {
t.Fatal(err)
Expand All @@ -68,6 +73,10 @@ func TestInvalidHostRequest(t *testing.T) {
}

func TestValidHostRequest(t *testing.T) {
Bot = &Engine{
Config: loadConfig(t),
}

req, err := http.NewRequest(http.MethodGet, "/config/all", nil)
if err != nil {
t.Fatal(err)
Expand All @@ -81,3 +90,43 @@ func TestValidHostRequest(t *testing.T) {
t.Errorf("Response returned wrong status code expected %v got %v", http.StatusOK, status)
}
}

func TestProfilerEnabledShouldEnableProfileEndPoint(t *testing.T) {
Bot = &Engine{
Config: loadConfig(t),
}

req, err := http.NewRequest(http.MethodGet, "/debug/pprof/", nil)
if err != nil {
t.Fatal(err)
}

req.Host = "localhost:9050"
resp := httptest.NewRecorder()
newRouter(true).ServeHTTP(resp, req)
if status := resp.Code; status != http.StatusNotFound {
t.Errorf("Response returned wrong status code expected %v got %v", http.StatusNotFound, status)
}

Bot.Config.Profiler.Enabled = true
Bot.Config.Profiler.MutexProfileFraction = 5
req, err = http.NewRequest(http.MethodGet, "/debug/pprof/", nil)
if err != nil {
t.Fatal(err)
}

mutexValue := runtime.SetMutexProfileFraction(10)
if mutexValue != 0 {
t.Fatalf("SetMutexProfileFraction() should be 0 on first set received: %v", mutexValue)
}

resp = httptest.NewRecorder()
newRouter(true).ServeHTTP(resp, req)
mutexValue = runtime.SetMutexProfileFraction(10)
if mutexValue != 5 {
t.Fatalf("SetMutexProfileFraction() should be 5 after setup received: %v", mutexValue)
}
if status := resp.Code; status != http.StatusOK {
t.Errorf("Response returned wrong status code expected %v got %v", http.StatusOK, status)
}
}
3 changes: 2 additions & 1 deletion testdata/configtest.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
"checkInterval": 1000000000
},
"profiler": {
"enabled": false
"enabled": false,
"mutex_profile_fraction": 0
},
"ntpclient": {
"enabled": 0,
Expand Down

0 comments on commit bc0c32d

Please sign in to comment.