Skip to content
This repository was archived by the owner on Nov 7, 2022. It is now read-only.

Commit e57bda2

Browse files
author
Paulo Janotti
authored
Add profile fractions for Mutex and Block profiling (#529)
* Add profile fractions for Mutex and Block profiling These two options need to be set in order to use the mutext contention and blocking profiling modes of pprof. * Coverage Tax 01 * Check added flags
1 parent ddbbf72 commit e57bda2

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

internal/pprofserver/pprofserver.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ import (
1818
"flag"
1919
"net/http"
2020
_ "net/http/pprof" // Needed to enable the performance profiler
21+
"runtime"
2122
"strconv"
2223

2324
"github.com/spf13/viper"
2425
"go.uber.org/zap"
2526
)
2627

2728
const (
28-
httpPprofPortCfg = "http-pprof-port"
29+
httpPprofPortCfg = "http-pprof-port"
30+
pprofBlockProfileFraction = "pprof-block-profile-fraction"
31+
pprofMutexProfileFraction = "pprof-mutex-profile-fraction"
2932
)
3033

3134
// AddFlags add the command-line flags used to control the Performance Profiler
@@ -35,6 +38,14 @@ func AddFlags(flags *flag.FlagSet) {
3538
httpPprofPortCfg,
3639
0,
3740
"Port to be used by golang net/http/pprof (Performance Profiler), the profiler is disabled if no port or 0 is specified.")
41+
flags.Int(
42+
pprofBlockProfileFraction,
43+
-1,
44+
"Fraction of blocking events that are profiled. A value <= 0 disables profiling. See runtime.SetBlockProfileRate for details.")
45+
flags.Int(
46+
pprofMutexProfileFraction,
47+
-1,
48+
"Fraction of mutex contention events that are profiled. A value <= 0 disables profiling. See runtime.SetMutexProfileFraction for details.")
3849
}
3950

4051
// SetupFromViper sets up the Performance Profiler (pprof) as an HTTP endpoint
@@ -45,6 +56,9 @@ func SetupFromViper(asyncErrorChannel chan<- error, v *viper.Viper, logger *zap.
4556
return nil
4657
}
4758

59+
runtime.SetBlockProfileRate(v.GetInt(pprofBlockProfileFraction))
60+
runtime.SetMutexProfileFraction(v.GetInt(pprofMutexProfileFraction))
61+
4862
logger.Info("Starting net/http/pprof server", zap.Int("port", port))
4963
go func() {
5064
if err := http.ListenAndServe(":"+strconv.Itoa(port), nil); err != http.ErrServerClosed {

internal/pprofserver/pprofserver_test.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,61 @@
1414

1515
package pprofserver
1616

17-
// TODO: Add tests
17+
import (
18+
"flag"
19+
"net/http"
20+
"runtime"
21+
"strconv"
22+
"testing"
23+
"time"
24+
25+
"github.com/spf13/viper"
26+
"go.uber.org/zap"
27+
)
28+
29+
func TestPerformanceProfilerFlags(t *testing.T) {
30+
fs := flag.NewFlagSet("test", flag.ExitOnError)
31+
AddFlags(fs)
32+
33+
args := []string{
34+
"--" + httpPprofPortCfg + "=1777",
35+
"--" + pprofBlockProfileFraction + "=5",
36+
"--" + pprofMutexProfileFraction + "=-1",
37+
}
38+
39+
if err := fs.Parse(args); err != nil {
40+
t.Fatalf("failed to parse arguments: %v", err)
41+
}
42+
}
43+
44+
func TestPerformanceProfilerServer(t *testing.T) {
45+
v := viper.New()
46+
const pprofPort = 17788
47+
v.Set(httpPprofPortCfg, pprofPort)
48+
v.Set(pprofBlockProfileFraction, 3)
49+
v.Set(pprofMutexProfileFraction, 5)
50+
51+
asyncErrChan := make(chan error, 1)
52+
if err := SetupFromViper(asyncErrChan, v, zap.NewNop()); err != nil {
53+
t.Fatalf("failed to setup pprof server: %v", err)
54+
}
55+
56+
// Give a chance for the server goroutine to run.
57+
runtime.Gosched()
58+
59+
client := &http.Client{}
60+
resp, err := client.Get("http://localhost:" + strconv.Itoa(pprofPort) + "/debug/pprof")
61+
if err != nil {
62+
t.Fatalf("failed to get a response from pprof server: %v", err)
63+
}
64+
defer resp.Body.Close()
65+
if resp.StatusCode != http.StatusOK {
66+
t.Fatalf("ppropf server response: got %v want %v", resp.StatusCode, http.StatusOK)
67+
}
68+
69+
select {
70+
case err := <-asyncErrChan:
71+
t.Fatalf("async err received from pprof: %v", err)
72+
case <-time.After(250 * time.Millisecond):
73+
}
74+
}

0 commit comments

Comments
 (0)