From 075be0f9578fa4a8e47aebbd3ddbdb1e0494c9db Mon Sep 17 00:00:00 2001 From: mattdurham Date: Wed, 27 Dec 2023 14:36:42 -0500 Subject: [PATCH] add max_cache_size (#6026) * add max_cache_size * add max_cache_size to converter * fix tests --- CHANGELOG.md | 2 ++ component/prometheus/relabel/relabel.go | 20 +++++++++++++------ component/prometheus/relabel/relabel_test.go | 14 ++++++++++++- .../prometheusconvert/component/relabel.go | 1 + .../components/prometheus.relabel.md | 3 ++- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2652fad76ac..260d8437159a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,8 @@ Main (unreleased) - Add support for Basic Auth for agent's web UI, including the APIs. (@hainenber) +- Add `max_cache_size` to `prometheus.relabel` to allow configurability instead of hard coded 100,000. (@mattdurham) + ### Bugfixes - Update `pyroscope.ebpf` to fix a logical bug causing to profile to many kthreads instead of regular processes https://github.com/grafana/pyroscope/pull/2778 (@korniltsev) diff --git a/component/prometheus/relabel/relabel.go b/component/prometheus/relabel/relabel.go index c7b39ad6b0f4..0f3b0c6dc9ac 100644 --- a/component/prometheus/relabel/relabel.go +++ b/component/prometheus/relabel/relabel.go @@ -46,15 +46,23 @@ type Arguments struct { MetricRelabelConfigs []*flow_relabel.Config `river:"rule,block,optional"` // Cache size to use for LRU cache. - //CacheSize int `river:"cache_size,attr,optional"` + CacheSize int `river:"max_cache_size,attr,optional"` } // SetToDefault implements river.Defaulter. -/*func (arg *Arguments) SetToDefault() { +func (arg *Arguments) SetToDefault() { *arg = Arguments{ - CacheSize: 500_000, + CacheSize: 100_000, } -}*/ +} + +// Validate implements river.Validator. +func (arg *Arguments) Validate() error { + if arg.CacheSize <= 0 { + return fmt.Errorf("max_cache_size must be greater than 0 and is %d", arg.CacheSize) + } + return nil +} // Exports holds values which are exported by the prometheus.relabel component. type Exports struct { @@ -88,7 +96,7 @@ var ( // New creates a new prometheus.relabel component. func New(o component.Options, args Arguments) (*Component, error) { - cache, err := lru.New[uint64, *labelAndID](100_000) + cache, err := lru.New[uint64, *labelAndID](args.CacheSize) if err != nil { return nil, err } @@ -210,7 +218,7 @@ func (c *Component) Update(args component.Arguments) error { defer c.mut.Unlock() newArgs := args.(Arguments) - c.clearCache(100_000) + c.clearCache(newArgs.CacheSize) c.mrc = flow_relabel.ComponentToPromRelabelConfigs(newArgs.MetricRelabelConfigs) c.fanout.UpdateChildren(newArgs.ForwardTo) diff --git a/component/prometheus/relabel/relabel_test.go b/component/prometheus/relabel/relabel_test.go index c6d2b2699031..d029498555b8 100644 --- a/component/prometheus/relabel/relabel_test.go +++ b/component/prometheus/relabel/relabel_test.go @@ -44,11 +44,22 @@ func TestUpdateReset(t *testing.T) { relabeller.relabel(0, lbls) require.True(t, relabeller.cache.Len() == 1) _ = relabeller.Update(Arguments{ + CacheSize: 100000, MetricRelabelConfigs: []*flow_relabel.Config{}, }) require.True(t, relabeller.cache.Len() == 0) } +func TestValidator(t *testing.T) { + args := Arguments{CacheSize: 0} + err := args.Validate() + require.Error(t, err) + + args.CacheSize = 1 + err = args.Validate() + require.NoError(t, err) +} + func TestNil(t *testing.T) { ls := labelstore.New(nil, prom.DefaultRegisterer) fanout := prometheus.NewInterceptor(nil, ls, prometheus.WithAppendHook(func(ref storage.SeriesRef, _ labels.Labels, _ int64, _ float64, _ storage.Appender) (storage.SeriesRef, error) { @@ -72,6 +83,7 @@ func TestNil(t *testing.T) { Action: "drop", }, }, + CacheSize: 100000, }) require.NotNil(t, relabeller) require.NoError(t, err) @@ -129,7 +141,6 @@ func BenchmarkCache(b *testing.B) { lbls := labels.FromStrings("__address__", "localhost") app := entry.Appender(context.Background()) - for i := 0; i < b.N; i++ { app.Append(0, lbls, time.Now().UnixMilli(), 0) } @@ -161,6 +172,7 @@ func generateRelabel(t *testing.T) *Component { Action: "replace", }, }, + CacheSize: 100_000, }) require.NotNil(t, relabeller) require.NoError(t, err) diff --git a/converter/internal/prometheusconvert/component/relabel.go b/converter/internal/prometheusconvert/component/relabel.go index de6ec420ec21..a3bee3c6b7dd 100644 --- a/converter/internal/prometheusconvert/component/relabel.go +++ b/converter/internal/prometheusconvert/component/relabel.go @@ -36,6 +36,7 @@ func toRelabelArguments(relabelConfigs []*prom_relabel.Config, forwardTo []stora return &relabel.Arguments{ ForwardTo: forwardTo, MetricRelabelConfigs: ToFlowRelabelConfigs(relabelConfigs), + CacheSize: 100_000, } } diff --git a/docs/sources/flow/reference/components/prometheus.relabel.md b/docs/sources/flow/reference/components/prometheus.relabel.md index 93645aec83b6..65cb02394d4a 100644 --- a/docs/sources/flow/reference/components/prometheus.relabel.md +++ b/docs/sources/flow/reference/components/prometheus.relabel.md @@ -56,6 +56,7 @@ The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- `forward_to` | `list(MetricsReceiver)` | Where the metrics should be forwarded to, after relabeling takes place. | | yes +`max_cache_size` | `int` | The maximum number of elements to hold in the relabeling cache. | 100,000 | no ## Blocks @@ -187,4 +188,4 @@ connection work correctly. Refer to the linked documentation for more details. {{% /admonition %}} - \ No newline at end of file +