Skip to content

Commit 5b7e8b2

Browse files
bwplotkakakkoyun
andauthored
collectors.GoCollector: Added rule support for granular metric configuration. (#1102)
* goCollector: Added rule support for granular metric configuration. Fixes: #1089 Signed-off-by: bwplotka <[email protected]> * Added compatibility mode with old options. (#1107) * Added compatibility mode with old options. Signed-off-by: bwplotka <[email protected]> * Copyright header. Signed-off-by: bwplotka <[email protected]> * Remove bucket option for now. (#1108) Signed-off-by: bwplotka <[email protected]> * collectors/GoCollector: Add tests and examples (#1109) * Add tests and examples Signed-off-by: Kemal Akkoyun <[email protected]> * Add docs for the presets Signed-off-by: Kemal Akkoyun <[email protected]> Co-authored-by: Kemal Akkoyun <[email protected]>
1 parent d44fbbe commit 5b7e8b2

7 files changed

+626
-181
lines changed

prometheus/collector.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ type Collector interface {
6969
// If a Collector collects the same metrics throughout its lifetime, its
7070
// Describe method can simply be implemented as:
7171
//
72-
// func (c customCollector) Describe(ch chan<- *Desc) {
73-
// DescribeByCollect(c, ch)
74-
// }
72+
// func (c customCollector) Describe(ch chan<- *Desc) {
73+
// DescribeByCollect(c, ch)
74+
// }
7575
//
7676
// However, this will not work if the metrics collected change dynamically over
7777
// the lifetime of the Collector in a way that their combined set of descriptors

prometheus/collectors/go_collector_latest.go

+127-59
Original file line numberDiff line numberDiff line change
@@ -16,77 +16,145 @@
1616

1717
package collectors
1818

19-
import "github.com/prometheus/client_golang/prometheus"
19+
import (
20+
"regexp"
2021

21-
//nolint:staticcheck // Ignore SA1019 until v2.
22-
type goOptions = prometheus.GoCollectorOptions
23-
type goOption func(o *goOptions)
22+
"github.com/prometheus/client_golang/prometheus"
23+
"github.com/prometheus/client_golang/prometheus/internal"
24+
)
25+
26+
var (
27+
// MetricsAll allows all the metrics to be collected from Go runtime.
28+
MetricsAll = GoRuntimeMetricsRule{regexp.MustCompile("/.*")}
29+
// MetricsGC allows only GC metrics to be collected from Go runtime.
30+
// e.g. go_gc_cycles_automatic_gc_cycles_total
31+
MetricsGC = GoRuntimeMetricsRule{regexp.MustCompile(`^/gc/.*`)}
32+
// MetricsMemory allows only memory metrics to be collected from Go runtime.
33+
// e.g. go_memory_classes_heap_free_bytes
34+
MetricsMemory = GoRuntimeMetricsRule{regexp.MustCompile(`^/memory/.*`)}
35+
// MetricsScheduler allows only scheduler metrics to be collected from Go runtime.
36+
// e.g. go_sched_goroutines_goroutines
37+
MetricsScheduler = GoRuntimeMetricsRule{regexp.MustCompile(`^/sched/.*`)}
38+
)
2439

40+
// WithGoCollectorMemStatsMetricsDisabled disables metrics that is gathered in runtime.MemStats structure such as:
41+
//
42+
// go_memstats_alloc_bytes
43+
// go_memstats_alloc_bytes_total
44+
// go_memstats_sys_bytes
45+
// go_memstats_lookups_total
46+
// go_memstats_mallocs_total
47+
// go_memstats_frees_total
48+
// go_memstats_heap_alloc_bytes
49+
// go_memstats_heap_sys_bytes
50+
// go_memstats_heap_idle_bytes
51+
// go_memstats_heap_inuse_bytes
52+
// go_memstats_heap_released_bytes
53+
// go_memstats_heap_objects
54+
// go_memstats_stack_inuse_bytes
55+
// go_memstats_stack_sys_bytes
56+
// go_memstats_mspan_inuse_bytes
57+
// go_memstats_mspan_sys_bytes
58+
// go_memstats_mcache_inuse_bytes
59+
// go_memstats_mcache_sys_bytes
60+
// go_memstats_buck_hash_sys_bytes
61+
// go_memstats_gc_sys_bytes
62+
// go_memstats_other_sys_bytes
63+
// go_memstats_next_gc_bytes
64+
//
65+
// so the metrics known from pre client_golang v1.12.0,
66+
//
67+
// NOTE(bwplotka): The above represents runtime.MemStats statistics, but they are
68+
// actually implemented using new runtime/metrics package. (except skipped go_memstats_gc_cpu_fraction
69+
// -- see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 for explanation).
70+
//
71+
// Some users might want to disable this on collector level (although you can use scrape relabelling on Prometheus),
72+
// because similar metrics can be now obtained using WithGoCollectorRuntimeMetrics. Note that the semantics of new
73+
// metrics might be different, plus the names can be change over time with different Go version.
74+
//
75+
// NOTE(bwplotka): Changing metric names can be tedious at times as the alerts, recording rules and dashboards have to be adjusted.
76+
// The old metrics are also very useful, with many guides and books written about how to interpret them.
77+
//
78+
// As a result our recommendation would be to stick with MemStats like metrics and enable other runtime/metrics if you are interested
79+
// in advanced insights Go provides. See ExampleGoCollector_WithAdvancedGoMetrics.
80+
func WithGoCollectorMemStatsMetricsDisabled() func(options *internal.GoCollectorOptions) {
81+
return func(o *internal.GoCollectorOptions) {
82+
o.DisableMemStatsLikeMetrics = true
83+
}
84+
}
85+
86+
// GoRuntimeMetricsRule allow enabling and configuring particular group of runtime/metrics.
87+
// TODO(bwplotka): Consider adding ability to adjust buckets.
88+
type GoRuntimeMetricsRule struct {
89+
// Matcher represents RE2 expression will match the runtime/metrics from https://golang.bg/src/runtime/metrics/description.go
90+
// Use `regexp.MustCompile` or `regexp.Compile` to create this field.
91+
Matcher *regexp.Regexp
92+
}
93+
94+
// WithGoCollectorRuntimeMetrics allows enabling and configuring particular group of runtime/metrics.
95+
// See the list of metrics https://golang.bg/src/runtime/metrics/description.go (pick the Go version you use there!).
96+
// You can use this option in repeated manner, which will add new rules. The order of rules is important, the last rule
97+
// that matches particular metrics is applied.
98+
func WithGoCollectorRuntimeMetrics(rules ...GoRuntimeMetricsRule) func(options *internal.GoCollectorOptions) {
99+
rs := make([]internal.GoCollectorRule, len(rules))
100+
for i, r := range rules {
101+
rs[i] = internal.GoCollectorRule{
102+
Matcher: r.Matcher,
103+
}
104+
}
105+
106+
return func(o *internal.GoCollectorOptions) {
107+
o.RuntimeMetricRules = append(o.RuntimeMetricRules, rs...)
108+
}
109+
}
110+
111+
// WithoutGoCollectorRuntimeMetrics allows disabling group of runtime/metrics that you might have added in WithGoCollectorRuntimeMetrics.
112+
// It behaves similarly to WithGoCollectorRuntimeMetrics just with deny-list semantics.
113+
func WithoutGoCollectorRuntimeMetrics(matchers ...*regexp.Regexp) func(options *internal.GoCollectorOptions) {
114+
rs := make([]internal.GoCollectorRule, len(matchers))
115+
for i, m := range matchers {
116+
rs[i] = internal.GoCollectorRule{
117+
Matcher: m,
118+
Deny: true,
119+
}
120+
}
121+
122+
return func(o *internal.GoCollectorOptions) {
123+
o.RuntimeMetricRules = append(o.RuntimeMetricRules, rs...)
124+
}
125+
}
126+
127+
// GoCollectionOption represents Go collection option flag.
128+
// Deprecated.
25129
type GoCollectionOption uint32
26130

27131
const (
28-
// GoRuntimeMemStatsCollection represents the metrics represented by runtime.MemStats structure such as
29-
// go_memstats_alloc_bytes
30-
// go_memstats_alloc_bytes_total
31-
// go_memstats_sys_bytes
32-
// go_memstats_lookups_total
33-
// go_memstats_mallocs_total
34-
// go_memstats_frees_total
35-
// go_memstats_heap_alloc_bytes
36-
// go_memstats_heap_sys_bytes
37-
// go_memstats_heap_idle_bytes
38-
// go_memstats_heap_inuse_bytes
39-
// go_memstats_heap_released_bytes
40-
// go_memstats_heap_objects
41-
// go_memstats_stack_inuse_bytes
42-
// go_memstats_stack_sys_bytes
43-
// go_memstats_mspan_inuse_bytes
44-
// go_memstats_mspan_sys_bytes
45-
// go_memstats_mcache_inuse_bytes
46-
// go_memstats_mcache_sys_bytes
47-
// go_memstats_buck_hash_sys_bytes
48-
// go_memstats_gc_sys_bytes
49-
// go_memstats_other_sys_bytes
50-
// go_memstats_next_gc_bytes
51-
// so the metrics known from pre client_golang v1.12.0, except skipped go_memstats_gc_cpu_fraction (see
52-
// https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 for explanation.
53-
//
54-
// NOTE that this mode represents runtime.MemStats statistics, but they are
55-
// actually implemented using new runtime/metrics package.
56-
// Deprecated: Use GoRuntimeMetricsCollection instead going forward.
132+
// GoRuntimeMemStatsCollection represents the metrics represented by runtime.MemStats structure.
133+
// Deprecated. Use WithGoCollectorMemStatsMetricsDisabled() function to disable those metrics in the collector.
57134
GoRuntimeMemStatsCollection GoCollectionOption = 1 << iota
58-
// GoRuntimeMetricsCollection is the new set of metrics represented by runtime/metrics package and follows
59-
// consistent naming. The exposed metric set depends on Go version, but it is controlled against
60-
// unexpected cardinality. This set has overlapping information with GoRuntimeMemStatsCollection, just with
61-
// new names. GoRuntimeMetricsCollection is what is recommended for using going forward.
135+
// GoRuntimeMetricsCollection is the new set of metrics represented by runtime/metrics package.
136+
// Deprecated. Use WithGoCollectorRuntimeMetrics(GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/.*")})
137+
// function to enable those metrics in the collector.
62138
GoRuntimeMetricsCollection
63139
)
64140

65-
// WithGoCollections allows enabling different collections for Go collector on top of base metrics
66-
// like go_goroutines, go_threads, go_gc_duration_seconds, go_memstats_last_gc_time_seconds, go_info.
67-
//
68-
// Check GoRuntimeMemStatsCollection and GoRuntimeMetricsCollection for more details. You can use none,
69-
// one or more collections at once. For example:
70-
// WithGoCollections(GoRuntimeMemStatsCollection | GoRuntimeMetricsCollection) means both GoRuntimeMemStatsCollection
71-
// metrics and GoRuntimeMetricsCollection will be exposed.
72-
//
73-
// The current default is GoRuntimeMemStatsCollection, so the compatibility mode with
74-
// client_golang pre v1.12 (move to runtime/metrics).
75-
//nolint:staticcheck // Ignore SA1019 until v2.
76-
func WithGoCollections(flags GoCollectionOption) func(options *prometheus.GoCollectorOptions) {
77-
return func(o *goOptions) {
78-
o.EnabledCollections = uint32(flags)
141+
// WithGoCollections allows enabling different collections for Go collector on top of base metrics.
142+
// Deprecated. Use WithGoCollectorRuntimeMetrics() and WithGoCollectorMemStatsMetricsDisabled() instead to control metrics.
143+
func WithGoCollections(flags GoCollectionOption) func(options *internal.GoCollectorOptions) {
144+
return func(options *internal.GoCollectorOptions) {
145+
if flags&GoRuntimeMemStatsCollection == 0 {
146+
WithGoCollectorMemStatsMetricsDisabled()(options)
147+
}
148+
149+
if flags&GoRuntimeMetricsCollection != 0 {
150+
WithGoCollectorRuntimeMetrics(GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/.*")})(options)
151+
}
79152
}
80153
}
81154

82155
// NewGoCollector returns a collector that exports metrics about the current Go
83-
// process using debug.GCStats using runtime/metrics.
84-
func NewGoCollector(opts ...goOption) prometheus.Collector {
85-
//nolint:staticcheck // Ignore SA1019 until v2.
86-
promPkgOpts := make([]func(o *prometheus.GoCollectorOptions), len(opts))
87-
for i, opt := range opts {
88-
promPkgOpts[i] = opt
89-
}
156+
// process using debug.GCStats (base metrics) and runtime/metrics (both in MemStats style and new ones).
157+
func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) prometheus.Collector {
90158
//nolint:staticcheck // Ignore SA1019 until v2.
91-
return prometheus.NewGoCollector(promPkgOpts...)
159+
return prometheus.NewGoCollector(opts...)
92160
}

0 commit comments

Comments
 (0)