diff --git a/cmd/alertmanager/main.go b/cmd/alertmanager/main.go index d44d58a8d1..06d697a055 100644 --- a/cmd/alertmanager/main.go +++ b/cmd/alertmanager/main.go @@ -42,6 +42,7 @@ import ( "github.com/prometheus/common/version" "github.com/prometheus/exporter-toolkit/web" webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag" + "go.uber.org/automaxprocs/maxprocs" "github.com/prometheus/alertmanager/api" "github.com/prometheus/alertmanager/cluster" @@ -194,6 +195,15 @@ func run() int { } compat.InitFromFlags(logger, ff) + if ff.EnableAutoGOMAXPROCS() { + l := func(format string, a ...interface{}) { + level.Info(logger).Log("component", "automaxprocs", "msg", fmt.Sprintf(strings.TrimPrefix(format, "maxprocs: "), a...)) + } + if _, err := maxprocs.Set(maxprocs.Logger(l)); err != nil { + level.Warn(logger).Log("msg", "Failed to set GOMAXPROCS automatically", "err", err) + } + } + err = os.MkdirAll(*dataDir, 0o777) if err != nil { level.Error(logger).Log("msg", "Unable to create data directory", "err", err) diff --git a/featurecontrol/featurecontrol.go b/featurecontrol/featurecontrol.go index 9ff7a2d8fd..4616a057fb 100644 --- a/featurecontrol/featurecontrol.go +++ b/featurecontrol/featurecontrol.go @@ -26,18 +26,21 @@ const ( FeatureReceiverNameInMetrics = "receiver-name-in-metrics" FeatureClassicMode = "classic-mode" FeatureUTF8StrictMode = "utf8-strict-mode" + FeatureAutoGOMAXPROCS = "auto-gomaxprocs" ) var AllowedFlags = []string{ FeatureReceiverNameInMetrics, FeatureClassicMode, FeatureUTF8StrictMode, + FeatureAutoGOMAXPROCS, } type Flagger interface { EnableReceiverNamesInMetrics() bool ClassicMode() bool UTF8StrictMode() bool + EnableAutoGOMAXPROCS() bool } type Flags struct { @@ -45,6 +48,7 @@ type Flags struct { enableReceiverNamesInMetrics bool classicMode bool utf8StrictMode bool + enableAutoGOMAXPROCS bool } func (f *Flags) EnableReceiverNamesInMetrics() bool { @@ -59,6 +63,10 @@ func (f *Flags) UTF8StrictMode() bool { return f.utf8StrictMode } +func (f *Flags) EnableAutoGOMAXPROCS() bool { + return f.enableAutoGOMAXPROCS +} + type flagOption func(flags *Flags) func enableReceiverNameInMetrics() flagOption { @@ -79,6 +87,12 @@ func enableUTF8StrictMode() flagOption { } } +func enableAutoGOMAXPROCS() flagOption { + return func(configs *Flags) { + configs.enableAutoGOMAXPROCS = true + } +} + func NewFlags(logger log.Logger, features string) (Flagger, error) { fc := &Flags{logger: logger} opts := []flagOption{} @@ -98,6 +112,9 @@ func NewFlags(logger log.Logger, features string) (Flagger, error) { case FeatureUTF8StrictMode: opts = append(opts, enableUTF8StrictMode()) level.Warn(logger).Log("msg", "UTF-8 strict mode enabled") + case FeatureAutoGOMAXPROCS: + opts = append(opts, enableAutoGOMAXPROCS()) + level.Warn(logger).Log("msg", "Automatically set GOMAXPROCS to match Linux container CPU quota") default: return nil, fmt.Errorf("Unknown option '%s' for --enable-feature", feature) } @@ -121,3 +138,5 @@ func (n NoopFlags) EnableReceiverNamesInMetrics() bool { return false } func (n NoopFlags) ClassicMode() bool { return false } func (n NoopFlags) UTF8StrictMode() bool { return false } + +func (n NoopFlags) EnableAutoGOMAXPROCS() bool { return false } diff --git a/go.mod b/go.mod index ac487a46b7..71051b8560 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/xlab/treeprint v1.2.0 go.uber.org/atomic v1.11.0 + go.uber.org/automaxprocs v1.5.3 golang.org/x/mod v0.18.0 golang.org/x/net v0.26.0 golang.org/x/text v0.16.0 diff --git a/go.sum b/go.sum index 9c87947bb0..0d8f4f45e2 100644 --- a/go.sum +++ b/go.sum @@ -411,6 +411,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= @@ -519,6 +521,8 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=