-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add default Go runtime metrics for /gc/gogc:percent, /gc/gomemlimit:bytes, /sched/gomaxprocs:threads #1559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add default Go runtime metrics for /gc/gogc:percent, /gc/gomemlimit:bytes, /sched/gomaxprocs:threads #1559
Changes from 9 commits
cd8445b
5d64fb7
17b3065
5d9b680
4490f8d
fb0afbe
0b3a6f0
6478f56
e4a5ade
a04c891
20ebd6c
ed4053d
b8a9eb7
23879d6
cd5a2a6
5eb377e
4a2cb15
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,10 +55,11 @@ func TestGoCollectorMarshalling(t *testing.T) { | |
} | ||
} | ||
|
||
func TestWithGoCollectorMemStatsMetricsDisabled(t *testing.T) { | ||
func TestWithBaseMetricsOnly(t *testing.T) { | ||
reg := prometheus.NewRegistry() | ||
reg.MustRegister(NewGoCollector( | ||
WithGoCollectorMemStatsMetricsDisabled(), | ||
WithGoCollectorRuntimeEnvVarsMetricsDisabled(), | ||
)) | ||
result, err := reg.Gather() | ||
if err != nil { | ||
|
@@ -117,6 +118,7 @@ func TestGoCollectorAllowList(t *testing.T) { | |
reg.MustRegister(NewGoCollector( | ||
WithGoCollectorMemStatsMetricsDisabled(), | ||
WithGoCollectorRuntimeMetrics(test.rules...), | ||
WithGoCollectorRuntimeEnvVarsMetricsDisabled(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we test somewhere how it looks with those enabled? |
||
)) | ||
result, err := reg.Gather() | ||
if err != nil { | ||
|
@@ -171,6 +173,7 @@ func TestGoCollectorDenyList(t *testing.T) { | |
reg.MustRegister(NewGoCollector( | ||
WithGoCollectorMemStatsMetricsDisabled(), | ||
WithoutGoCollectorRuntimeMetrics(test.matchers...), | ||
WithGoCollectorRuntimeEnvVarsMetricsDisabled(), | ||
)) | ||
result, err := reg.Gather() | ||
if err != nil { | ||
|
@@ -214,6 +217,7 @@ func ExampleGoCollector_WithAdvancedGoMetrics() { | |
}, | ||
), | ||
WithoutGoCollectorRuntimeMetrics(regexp.MustCompile("^/gc/.*")), | ||
WithGoCollectorRuntimeEnvVarsMetricsDisabled(), | ||
)) | ||
|
||
http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{})) | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -279,3 +279,8 @@ type memStatsMetrics []struct { | |||
eval func(*runtime.MemStats) float64 | ||||
valType ValueType | ||||
} | ||||
|
||||
type runtimeEnvVarsMetrics []struct { // I couldn't come up with a better name. Any suggestions? | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! I see where you go with this. This way would totally work, but it's extra structures in many places. There is a way to simplify this by reusing generic flow, so by default adding appropriate regexes to
I think we can add that by default, then fix tests. We could even test if |
||||
desc *Desc | ||||
origMetricName string | ||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright 2024 The Prometheus Authors | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
//go:build !go1.21 | ||
// +build !go1.21 | ||
|
||
package prometheus | ||
|
||
func goRuntimeEnvVarsMetrics() runtimeEnvVarsMetrics { | ||
return runtimeEnvVarsMetrics{ | ||
{ | ||
desc: NewDesc( | ||
"go_gomaxprocs", | ||
"Value of GOMAXPROCS, i.e number of usable threads.", | ||
nil, nil, | ||
), | ||
origMetricName: "/sched/gomaxprocs:threads", | ||
}, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2024 The Prometheus Authors | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
//go:build go1.21 | ||
// +build go1.21 | ||
|
||
package prometheus | ||
|
||
func goRuntimeEnvVarsMetrics() runtimeEnvVarsMetrics { | ||
return runtimeEnvVarsMetrics{ | ||
{ | ||
desc: NewDesc( | ||
"go_gogc_percent", | ||
"Value of GOGC (percentage).", | ||
nil, nil, | ||
), | ||
origMetricName: "/gc/gogc:percent", | ||
}, | ||
{ | ||
desc: NewDesc( | ||
"go_gomemlimit", | ||
"Value of GOMEMLIMIT (bytes).", | ||
nil, nil, | ||
), | ||
origMetricName: "/gc/gomemlimit:bytes", | ||
}, | ||
{ | ||
desc: NewDesc( | ||
"go_gomaxprocs", | ||
"Value of GOMAXPROCS, i.e number of usable threads.", | ||
nil, nil, | ||
), | ||
origMetricName: "/sched/gomaxprocs:threads", | ||
}, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,39 +74,62 @@ func addExpectedRuntimeMetrics(metrics map[string]struct{}) map[string]struct{} | |
return metrics | ||
} | ||
|
||
func addExpectedEnvVarsMetrics(metrics map[string]struct{}) map[string]struct{} { | ||
for _, m := range goRuntimeEnvVarsMetrics() { | ||
metrics[m.desc.fqName] = struct{}{} | ||
} | ||
return metrics | ||
} | ||
|
||
func TestGoCollector_ExposedMetrics(t *testing.T) { | ||
for _, tcase := range []struct { | ||
opts internal.GoCollectorOptions | ||
expectedFQNameSet map[string]struct{} | ||
}{ | ||
{ | ||
opts: internal.GoCollectorOptions{ | ||
DisableMemStatsLikeMetrics: true, | ||
DisableMemStatsLikeMetrics: true, | ||
DisableRuntimeEnvVarsMetrics: true, | ||
}, | ||
expectedFQNameSet: expectedBaseMetrics(), | ||
}, | ||
{ | ||
// Default, only MemStats. | ||
// Default, only Memstats and RuntimeEnvVars. | ||
expectedFQNameSet: addExpectedEnvVarsMetrics(addExpectedRuntimeMemStats(expectedBaseMetrics())), | ||
}, | ||
{ | ||
// Only MemStats. | ||
opts: internal.GoCollectorOptions{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's use default function then? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mind using our new internal.GoCollector default etc here? |
||
DisableRuntimeEnvVarsMetrics: true, | ||
}, | ||
expectedFQNameSet: addExpectedRuntimeMemStats(expectedBaseMetrics()), | ||
}, | ||
{ | ||
// Get all runtime/metrics without MemStats. | ||
// Get all runtime/metrics without MemStats nor RuntimeEnvVars. | ||
opts: internal.GoCollectorOptions{ | ||
DisableMemStatsLikeMetrics: true, | ||
DisableMemStatsLikeMetrics: true, | ||
DisableRuntimeEnvVarsMetrics: true, | ||
RuntimeMetricRules: []internal.GoCollectorRule{ | ||
{Matcher: regexp.MustCompile("/.*")}, | ||
}, | ||
}, | ||
expectedFQNameSet: addExpectedRuntimeMetrics(expectedBaseMetrics()), | ||
}, | ||
{ | ||
// Get all runtime/metrics and MemStats. | ||
// Get all runtime/metrics, MemStats and RuntimeEnvVars. | ||
opts: internal.GoCollectorOptions{ | ||
RuntimeMetricRules: []internal.GoCollectorRule{ | ||
{Matcher: regexp.MustCompile("/.*")}, | ||
}, | ||
}, | ||
expectedFQNameSet: addExpectedRuntimeMemStats(addExpectedRuntimeMetrics(expectedBaseMetrics())), | ||
expectedFQNameSet: addExpectedEnvVarsMetrics(addExpectedRuntimeMemStats(addExpectedRuntimeMetrics(expectedBaseMetrics()))), | ||
}, | ||
{ | ||
// Only RuntimeEnvVars. | ||
opts: internal.GoCollectorOptions{ | ||
DisableMemStatsLikeMetrics: true, | ||
}, | ||
expectedFQNameSet: addExpectedEnvVarsMetrics(expectedBaseMetrics()), | ||
}, | ||
} { | ||
if ok := t.Run("", func(t *testing.T) { | ||
|
@@ -229,6 +252,7 @@ func collectGoMetrics(t *testing.T, opts internal.GoCollectorOptions) []Metric { | |
o.DisableMemStatsLikeMetrics = opts.DisableMemStatsLikeMetrics | ||
o.RuntimeMetricSumForHist = opts.RuntimeMetricSumForHist | ||
o.RuntimeMetricRules = opts.RuntimeMetricRules | ||
o.DisableRuntimeEnvVarsMetrics = opts.DisableRuntimeEnvVarsMetrics | ||
}).(*goCollector) | ||
|
||
// Collect all metrics. | ||
|
Uh oh!
There was an error while loading. Please reload this page.