diff --git a/go.mod b/go.mod index bdc799dc91d..443053c2529 100644 --- a/go.mod +++ b/go.mod @@ -92,7 +92,7 @@ require ( github.com/grafana/grafana-cloud-migration-snapshot v1.0.0 // @grafana/grafana-operator-experience-squad github.com/grafana/grafana-google-sdk-go v0.1.0 // @grafana/partner-datasources github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 // @grafana/grafana-backend-group - github.com/grafana/grafana-plugin-sdk-go v0.237.0 // @grafana/plugins-platform-backend + github.com/grafana/grafana-plugin-sdk-go v0.238.0 // @grafana/plugins-platform-backend github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701190119-78f9c0fd4144 // @grafana/grafana-app-platform-squad github.com/grafana/grafana/pkg/apiserver v0.0.0-20240708134731-e9876749d440 // @grafana/grafana-app-platform-squad // This needs to be here for other projects that import grafana/grafana diff --git a/go.sum b/go.sum index b960ce93ae3..e9234a73b2d 100644 --- a/go.sum +++ b/go.sum @@ -2336,8 +2336,8 @@ github.com/grafana/grafana-google-sdk-go v0.1.0/go.mod h1:Vo2TKWfDVmNTELBUM+3lkr github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 h1:r+mU5bGMzcXCRVAuOrTn54S80qbfVkvTdUJZfSfTNbs= github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79/go.mod h1:wc6Hbh3K2TgCUSfBC/BOzabItujtHMESZeFk5ZhdxhQ= github.com/grafana/grafana-plugin-sdk-go v0.114.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk= -github.com/grafana/grafana-plugin-sdk-go v0.237.0 h1:sxif4tl9ocYSVyeCtGijWQbW2ygfEOFGKQTCQ/ZX99M= -github.com/grafana/grafana-plugin-sdk-go v0.237.0/go.mod h1:4TgwJYqX8N27PIwEpa2gBEQyWsUW4rIQYGsrkhcgOgY= +github.com/grafana/grafana-plugin-sdk-go v0.238.0 h1:+LPuhUCBiQJEd571+ymA4WsJiiafbRECdX67B6YYN64= +github.com/grafana/grafana-plugin-sdk-go v0.238.0/go.mod h1:4TgwJYqX8N27PIwEpa2gBEQyWsUW4rIQYGsrkhcgOgY= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701190119-78f9c0fd4144 h1:FA9896cLHomvfJcEgTAEhx8q5qGsV1dhuOfnEHM2b+U= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701190119-78f9c0fd4144/go.mod h1:DkxMin+qOh1Fgkxfbt+CUfBqqsCQJMG9op8Os/irBPA= github.com/grafana/grafana/pkg/apiserver v0.0.0-20240708134731-e9876749d440 h1:833vWSgndCcOXycwCq2Y98W8+W2ouuuhTL+Gf3BNKg8= diff --git a/go.work.sum b/go.work.sum index 2b684f59699..badd95ee56b 100644 --- a/go.work.sum +++ b/go.work.sum @@ -895,7 +895,6 @@ golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/plot v0.10.1 h1:dnifSs43YJuNMDzB7v8wV64O4ABBHReuAVAoBxqBqS4= diff --git a/pkg/promlib/go.mod b/pkg/promlib/go.mod index 5839f9bf919..7e81dac679e 100644 --- a/pkg/promlib/go.mod +++ b/pkg/promlib/go.mod @@ -3,7 +3,7 @@ module github.com/grafana/grafana/pkg/promlib go 1.21.10 require ( - github.com/grafana/grafana-plugin-sdk-go v0.237.0 + github.com/grafana/grafana-plugin-sdk-go v0.238.0 github.com/json-iterator/go v1.1.12 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/prometheus/client_golang v1.19.1 diff --git a/pkg/promlib/go.sum b/pkg/promlib/go.sum index 4b21b883c52..68664903fe5 100644 --- a/pkg/promlib/go.sum +++ b/pkg/promlib/go.sum @@ -80,7 +80,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/grafana/grafana-plugin-sdk-go v0.237.0 h1:sxif4tl9ocYSVyeCtGijWQbW2ygfEOFGKQTCQ/ZX99M= +github.com/grafana/grafana-plugin-sdk-go v0.238.0 h1:+LPuhUCBiQJEd571+ymA4WsJiiafbRECdX67B6YYN64= github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= github.com/grafana/pyroscope-go/godeltaprof v0.1.7 h1:C11j63y7gymiW8VugJ9ZW0pWfxTZugdSJyC48olk5KY= github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db h1:7aN5cccjIqCLTzedH7MZzRZt5/lsAHch6Z3L2ZGn5FA= diff --git a/pkg/services/apiserver/standalone/options/options.go b/pkg/services/apiserver/standalone/options/options.go index 7d1f25efdcd..fb7f69d5d9d 100644 --- a/pkg/services/apiserver/standalone/options/options.go +++ b/pkg/services/apiserver/standalone/options/options.go @@ -15,6 +15,7 @@ type Options struct { RecommendedOptions *genericoptions.RecommendedOptions TracingOptions *TracingOptions MetricsOptions *MetricsOptions + ProfilingOptions *ProfilingOptions ServerRunOptions *genericoptions.ServerRunOptions StorageOptions *options.StorageOptions } @@ -26,6 +27,7 @@ func New(logger log.Logger, codec runtime.Codec) *Options { RecommendedOptions: options.NewRecommendedOptions(codec), TracingOptions: NewTracingOptions(logger), MetricsOptions: NewMetricsOptions(logger), + ProfilingOptions: NewProfilingOptions(logger), ServerRunOptions: genericoptions.NewServerRunOptions(), StorageOptions: options.NewStorageOptions(), } @@ -37,6 +39,7 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) { o.RecommendedOptions.AddFlags(fs) o.TracingOptions.AddFlags(fs) o.MetricsOptions.AddFlags(fs) + o.ProfilingOptions.AddFlags(fs) o.ServerRunOptions.AddUniversalFlags(fs) } @@ -57,6 +60,10 @@ func (o *Options) Validate() []error { return errs } + if errs := o.ProfilingOptions.Validate(); len(errs) != 0 { + return errs + } + if errs := o.ServerRunOptions.Validate(); len(errs) != 0 { return errs } @@ -168,6 +175,12 @@ func (o *Options) ApplyTo(serverConfig *genericapiserver.RecommendedConfig) erro } } + if o.ProfilingOptions != nil { + if err := o.ProfilingOptions.ApplyTo(serverConfig); err != nil { + return err + } + } + if o.ServerRunOptions != nil { if err := o.ServerRunOptions.ApplyTo(&serverConfig.Config); err != nil { return err diff --git a/pkg/services/apiserver/standalone/options/profiling.go b/pkg/services/apiserver/standalone/options/profiling.go new file mode 100644 index 00000000000..073ef7d6e0f --- /dev/null +++ b/pkg/services/apiserver/standalone/options/profiling.go @@ -0,0 +1,46 @@ +package options + +import ( + "runtime" + + "github.com/grafana/grafana/pkg/infra/log" + "github.com/spf13/pflag" + genericapiserver "k8s.io/apiserver/pkg/server" +) + +type ProfilingOptions struct { + logger log.Logger + blockProfilingRate int + mutexProfilingRate int +} + +func NewProfilingOptions(logger log.Logger) *ProfilingOptions { + return &ProfilingOptions{ + logger: logger, + } +} + +func (o *ProfilingOptions) AddFlags(fs *pflag.FlagSet) { + fs.IntVar(&o.blockProfilingRate, "grafana.profiling.block-rate", 0, "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.") + fs.IntVar(&o.mutexProfilingRate, "grafana.profiling.mutex-rate", 0, "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.") +} + +func (o *ProfilingOptions) Validate() []error { + return nil +} + +func (o *ProfilingOptions) ApplyTo(config *genericapiserver.RecommendedConfig) error { + if !config.EnableProfiling { + return nil + } + + // We bring our own block/mutex profiling configuration + config.EnableContentionProfiling = false + + runtime.SetBlockProfileRate(o.blockProfilingRate) + runtime.SetMutexProfileFraction(o.mutexProfilingRate) + + o.logger.Info("Profiling enabled", "blockProfileRate", o.blockProfilingRate, "mutexProfileRate", o.mutexProfilingRate) + + return nil +}