Profiling: Enhance configuration and docs (#90048)

Co-authored-by: Dave Henderson <dave.henderson@grafana.com>
This commit is contained in:
Marcus Efraimsson
2024-07-09 17:48:16 +02:00
committed by GitHub
parent 8a6e92c0c9
commit fc8a5cf468
9 changed files with 160 additions and 51 deletions

View File

@@ -77,7 +77,7 @@ func RunServer(opts ServerOptions) error {
}
}()
if err := setupProfiling(Profile, ProfileAddr, ProfilePort); err != nil {
if err := setupProfiling(Profile, ProfileAddr, ProfilePort, ProfileBlockRate, ProfileMutexFraction); err != nil {
return err
}
if err := setupTracing(Tracing, TracingFile, logger); err != nil {

View File

@@ -12,24 +12,30 @@ import (
)
const (
profilingEnabledEnvName = "GF_DIAGNOSTICS_PROFILING_ENABLED"
profilingAddrEnvName = "GF_DIAGNOSTICS_PROFILING_ADDR"
profilingPortEnvName = "GF_DIAGNOSTICS_PROFILING_PORT"
tracingEnabledEnvName = "GF_DIAGNOSTICS_TRACING_ENABLED"
tracingFileEnvName = "GF_DIAGNOSTICS_TRACING_FILE"
profilingEnabledEnvName = "GF_DIAGNOSTICS_PROFILING_ENABLED"
profilingAddrEnvName = "GF_DIAGNOSTICS_PROFILING_ADDR"
profilingPortEnvName = "GF_DIAGNOSTICS_PROFILING_PORT"
profilingBlockRateEnvName = "GF_DIAGNOSTICS_PROFILING_BLOCK_RATE"
profilingMutexRateEnvName = "GF_DIAGNOSTICS_PROFILING_MUTEX_RATE"
tracingEnabledEnvName = "GF_DIAGNOSTICS_TRACING_ENABLED"
tracingFileEnvName = "GF_DIAGNOSTICS_TRACING_FILE"
)
type profilingDiagnostics struct {
enabled bool
addr string
port uint64
enabled bool
addr string
port uint64
blockRate int
mutexRate int
}
func newProfilingDiagnostics(enabled bool, addr string, port uint64) *profilingDiagnostics {
func newProfilingDiagnostics(enabled bool, addr string, port uint64, blockRate int, mutexRate int) *profilingDiagnostics {
return &profilingDiagnostics{
enabled: enabled,
addr: addr,
port: port,
enabled: enabled,
addr: addr,
port: port,
blockRate: blockRate,
mutexRate: mutexRate,
}
}
@@ -57,6 +63,24 @@ func (pd *profilingDiagnostics) overrideWithEnv() error {
pd.port = port
}
blockRateEnv := os.Getenv(profilingBlockRateEnvName)
if blockRateEnv != "" {
blockRate, err := strconv.Atoi(blockRateEnv)
if err != nil {
return fmt.Errorf("failed to parse %s environment variable as int", profilingBlockRateEnvName)
}
pd.blockRate = blockRate
}
mutexFractionEnv := os.Getenv(profilingMutexRateEnvName)
if mutexFractionEnv != "" {
mutexProfileFraction, err := strconv.Atoi(mutexFractionEnv)
if err != nil {
return fmt.Errorf("failed to parse %s environment variable as int", profilingMutexRateEnvName)
}
pd.mutexRate = mutexProfileFraction
}
return nil
}
@@ -90,15 +114,17 @@ func (td *tracingDiagnostics) overrideWithEnv() error {
return nil
}
func setupProfiling(profile bool, profileAddr string, profilePort uint64) error {
profileDiagnostics := newProfilingDiagnostics(profile, profileAddr, profilePort)
func setupProfiling(profile bool, profileAddr string, profilePort uint64, blockRate int, mutexFraction int) error {
profileDiagnostics := newProfilingDiagnostics(profile, profileAddr, profilePort, blockRate, mutexFraction)
if err := profileDiagnostics.overrideWithEnv(); err != nil {
return err
}
if profileDiagnostics.enabled {
fmt.Println("diagnostics: pprof profiling enabled", "addr", profileDiagnostics.addr, "port", profileDiagnostics.port)
runtime.SetBlockProfileRate(1)
fmt.Println("diagnostics: pprof profiling enabled", "addr", profileDiagnostics.addr, "port", profileDiagnostics.port, "blockProfileRate", profileDiagnostics.blockRate, "mutexProfileRate", profileDiagnostics.mutexRate)
runtime.SetBlockProfileRate(profileDiagnostics.blockRate)
runtime.SetMutexProfileFraction(profileDiagnostics.mutexRate)
go func() {
// TODO: We should enable the linter and fix G114 here.
// G114: Use of net/http serve function that has no support for setting timeouts (gosec)

View File

@@ -9,17 +9,21 @@ import (
func TestProfilingDiagnostics(t *testing.T) {
tcs := []struct {
defaults *profilingDiagnostics
enabledEnv string
addrEnv string
portEnv string
expected *profilingDiagnostics
defaults *profilingDiagnostics
enabledEnv string
addrEnv string
portEnv string
blockRateEnv string
mutexRateEnv string
expected *profilingDiagnostics
}{
{defaults: newProfilingDiagnostics(false, "localhost", 6060), enabledEnv: "", addrEnv: "", portEnv: "", expected: newProfilingDiagnostics(false, "localhost", 6060)},
{defaults: newProfilingDiagnostics(true, "0.0.0.0", 8080), enabledEnv: "", addrEnv: "", portEnv: "", expected: newProfilingDiagnostics(true, "0.0.0.0", 8080)},
{defaults: newProfilingDiagnostics(false, "", 6060), enabledEnv: "false", addrEnv: "", portEnv: "8080", expected: newProfilingDiagnostics(false, "", 8080)},
{defaults: newProfilingDiagnostics(false, "localhost", 6060), enabledEnv: "true", addrEnv: "0.0.0.0", portEnv: "8080", expected: newProfilingDiagnostics(true, "0.0.0.0", 8080)},
{defaults: newProfilingDiagnostics(false, "127.0.0.1", 6060), enabledEnv: "true", addrEnv: "", portEnv: "", expected: newProfilingDiagnostics(true, "127.0.0.1", 6060)},
{defaults: newProfilingDiagnostics(false, "localhost", 6060, 0, 0), enabledEnv: "", addrEnv: "", portEnv: "", expected: newProfilingDiagnostics(false, "localhost", 6060, 0, 0)},
{defaults: newProfilingDiagnostics(true, "0.0.0.0", 8080, 0, 0), enabledEnv: "", addrEnv: "", portEnv: "", expected: newProfilingDiagnostics(true, "0.0.0.0", 8080, 0, 0)},
{defaults: newProfilingDiagnostics(false, "", 6060, 0, 0), enabledEnv: "false", addrEnv: "", portEnv: "8080", expected: newProfilingDiagnostics(false, "", 8080, 0, 0)},
{defaults: newProfilingDiagnostics(false, "localhost", 6060, 0, 0), enabledEnv: "true", addrEnv: "0.0.0.0", portEnv: "8080", expected: newProfilingDiagnostics(true, "0.0.0.0", 8080, 0, 0)},
{defaults: newProfilingDiagnostics(false, "127.0.0.1", 6060, 0, 0), enabledEnv: "true", addrEnv: "", portEnv: "", expected: newProfilingDiagnostics(true, "127.0.0.1", 6060, 0, 0)},
{defaults: newProfilingDiagnostics(true, "localhost", 6060, 0, 0), enabledEnv: "", addrEnv: "", portEnv: "", blockRateEnv: "3", mutexRateEnv: "4", expected: newProfilingDiagnostics(true, "localhost", 6060, 3, 4)},
{defaults: newProfilingDiagnostics(true, "localhost", 6060, 0, 0), enabledEnv: "", addrEnv: "", portEnv: "", expected: newProfilingDiagnostics(true, "localhost", 6060, 0, 0)},
}
for i, tc := range tcs {
@@ -33,6 +37,12 @@ func TestProfilingDiagnostics(t *testing.T) {
if tc.portEnv != "" {
t.Setenv(profilingPortEnvName, tc.portEnv)
}
if tc.blockRateEnv != "" {
t.Setenv(profilingBlockRateEnvName, tc.blockRateEnv)
}
if tc.mutexRateEnv != "" {
t.Setenv(profilingMutexRateEnvName, tc.mutexRateEnv)
}
err := tc.defaults.overrideWithEnv()
assert.NoError(t, err)
assert.Exactly(t, tc.expected, tc.defaults)

View File

@@ -1,21 +1,28 @@
package commands
import "github.com/urfave/cli/v2"
import (
"runtime"
"github.com/urfave/cli/v2"
)
// flags for the grafana server command(s)
var (
ConfigFile string
HomePath string
PidFile string
Packaging string
ConfigOverrides string
Version bool
VerboseVersion bool
Profile bool
ProfileAddr string
ProfilePort uint64
Tracing bool
TracingFile string
ConfigFile string
HomePath string
PidFile string
Packaging string
ConfigOverrides string
Version bool
VerboseVersion bool
Profile bool
ProfileAddr string
ProfilePort uint64
ProfileBlockRate int
ProfileMutexFraction int
ProfileContention bool
Tracing bool
TracingFile string
)
var commonFlags = []cli.Flag{
@@ -75,6 +82,18 @@ var commonFlags = []cli.Flag{
Usage: "Define custom port for profiling",
Destination: &ProfilePort,
},
&cli.IntFlag{
Name: "profile-block-rate",
Value: 1,
Usage: "Controls the fraction of goroutine blocking events that are reported in the blocking profile. The profiler aims to sample an average of one blocking event per rate nanoseconds spent blocked. To turn off profiling entirely, use 0",
Destination: &ProfileBlockRate,
},
&cli.IntFlag{
Name: "profile-mutex-rate",
Value: runtime.SetMutexProfileFraction(-1),
Usage: "Controls the fraction of mutex contention events that are reported in the mutex profile. On average 1/rate events are reported. To turn off mutex profiling entirely, use 0",
Destination: &ProfileMutexFraction,
},
&cli.BoolFlag{
Name: "tracing",
Value: false,

View File

@@ -54,7 +54,7 @@ func RunTargetServer(opts ServerOptions) error {
}
}()
if err := setupProfiling(Profile, ProfileAddr, ProfilePort); err != nil {
if err := setupProfiling(Profile, ProfileAddr, ProfilePort, ProfileBlockRate, ProfileMutexFraction); err != nil {
return err
}
if err := setupTracing(Tracing, TracingFile, logger); err != nil {