From 5a6e26556b3b4e8e7874cc00e06eeea94ea913ee Mon Sep 17 00:00:00 2001 From: DrAuYueng Date: Thu, 17 Feb 2022 05:12:47 +0800 Subject: [PATCH] Add an option to use the external labels as selectors for the remote read endpoint (#10254) * An option to ignore external_labels Signed-off-by: DrAuYueng --- config/config.go | 8 +++-- config/config_test.go | 12 ++++--- docs/configuration/configuration.md | 3 ++ storage/remote/storage.go | 6 +++- storage/remote/storage_test.go | 53 +++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 8 deletions(-) diff --git a/config/config.go b/config/config.go index 6c66f37c0..7dc733fc0 100644 --- a/config/config.go +++ b/config/config.go @@ -203,8 +203,9 @@ var ( // DefaultRemoteReadConfig is the default remote read configuration. DefaultRemoteReadConfig = RemoteReadConfig{ - RemoteTimeout: model.Duration(1 * time.Minute), - HTTPClientConfig: config.DefaultHTTPClientConfig, + RemoteTimeout: model.Duration(1 * time.Minute), + HTTPClientConfig: config.DefaultHTTPClientConfig, + FilterExternalLabels: true, } // DefaultStorageConfig is the default TSDB/Exemplar storage configuration. @@ -854,6 +855,9 @@ type RemoteReadConfig struct { // RequiredMatchers is an optional list of equality matchers which have to // be present in a selector to query the remote read endpoint. RequiredMatchers model.LabelSet `yaml:"required_matchers,omitempty"` + + // Whether to use the external labels as selectors for the remote read endpoint. + FilterExternalLabels bool `yaml:"filter_external_labels,omitempty"` } // SetDirectory joins any relative file paths with dir. diff --git a/config/config_test.go b/config/config_test.go index 5b78642b8..2fa2e5f6c 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -130,11 +130,12 @@ var expectedConf = &Config{ RemoteReadConfigs: []*RemoteReadConfig{ { - URL: mustParseURL("http://remote1/read"), - RemoteTimeout: model.Duration(1 * time.Minute), - ReadRecent: true, - Name: "default", - HTTPClientConfig: config.DefaultHTTPClientConfig, + URL: mustParseURL("http://remote1/read"), + RemoteTimeout: model.Duration(1 * time.Minute), + ReadRecent: true, + Name: "default", + HTTPClientConfig: config.DefaultHTTPClientConfig, + FilterExternalLabels: true, }, { URL: mustParseURL("http://remote3/read"), @@ -149,6 +150,7 @@ var expectedConf = &Config{ }, FollowRedirects: true, }, + FilterExternalLabels: true, }, }, diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index 48c0af8eb..1f0e26379 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -2868,6 +2868,9 @@ tls_config: # Configure whether HTTP requests follow HTTP 3xx redirects. [ follow_redirects: | default = true ] + +# Whether to use the external labels as selectors for the remote read endpoint. +[ filter_external_labels: | default = true ] ``` There is a list of diff --git a/storage/remote/storage.go b/storage/remote/storage.go index c82db1f9d..4de015e73 100644 --- a/storage/remote/storage.go +++ b/storage/remote/storage.go @@ -118,9 +118,13 @@ func (s *Storage) ApplyConfig(conf *config.Config) error { return err } + externalLabels := conf.GlobalConfig.ExternalLabels + if !rrConf.FilterExternalLabels { + externalLabels = make(labels.Labels, 0) + } queryables = append(queryables, NewSampleAndChunkQueryableClient( c, - conf.GlobalConfig.ExternalLabels, + externalLabels, labelsToEqualityMatchers(rrConf.RequiredMatchers), rrConf.ReadRecent, s.localStartTimeCallback, diff --git a/storage/remote/storage_test.go b/storage/remote/storage_test.go index 6254c6919..da2b689c0 100644 --- a/storage/remote/storage_test.go +++ b/storage/remote/storage_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/require" "github.com/prometheus/prometheus/config" + "github.com/prometheus/prometheus/model/labels" ) func TestStorageLifecycle(t *testing.T) { @@ -80,3 +81,55 @@ func TestUpdateRemoteReadConfigs(t *testing.T) { err := s.Close() require.NoError(t, err) } + +func TestFilterExternalLabels(t *testing.T) { + dir := t.TempDir() + + s := NewStorage(nil, nil, nil, dir, defaultFlushDeadline, nil) + + conf := &config.Config{ + GlobalConfig: config.GlobalConfig{ + ExternalLabels: labels.Labels{labels.Label{Name: "foo", Value: "bar"}}, + }, + } + require.NoError(t, s.ApplyConfig(conf)) + require.Equal(t, 0, len(s.queryables)) + + conf.RemoteReadConfigs = []*config.RemoteReadConfig{ + &config.DefaultRemoteReadConfig, + } + + require.NoError(t, s.ApplyConfig(conf)) + require.Equal(t, 1, len(s.queryables)) + require.Equal(t, 1, len(s.queryables[0].(*sampleAndChunkQueryableClient).externalLabels)) + + err := s.Close() + require.NoError(t, err) +} + +func TestIgnoreExternalLabels(t *testing.T) { + dir := t.TempDir() + + s := NewStorage(nil, nil, nil, dir, defaultFlushDeadline, nil) + + conf := &config.Config{ + GlobalConfig: config.GlobalConfig{ + ExternalLabels: labels.Labels{labels.Label{Name: "foo", Value: "bar"}}, + }, + } + require.NoError(t, s.ApplyConfig(conf)) + require.Equal(t, 0, len(s.queryables)) + + conf.RemoteReadConfigs = []*config.RemoteReadConfig{ + &config.DefaultRemoteReadConfig, + } + + conf.RemoteReadConfigs[0].FilterExternalLabels = false + + require.NoError(t, s.ApplyConfig(conf)) + require.Equal(t, 1, len(s.queryables)) + require.Equal(t, 0, len(s.queryables[0].(*sampleAndChunkQueryableClient).externalLabels)) + + err := s.Close() + require.NoError(t, err) +}