Skip to content
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

Merge the processors overrides set through runtime overrides and user-configurable overrides #3125

Merged
merged 2 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## main / unreleased

* [CHANGE] TraceQL/Structural operators performance improvement. [#3088](https://github.com/grafana/tempo/pull/3088) (@joe-elliott)
* [CHANGE] Merge the processors overrides set through runtime overrides and user-configurable overrides [#3125](https://github.com/grafana/tempo/pull/3125) (@kvrhdn)
* [FEATURE] Introduce list_blocks_concurrency on GCS and S3 backends to control backend load and performance. [#2652](https://github.com/grafana/tempo/pull/2652) (@zalegrala)
* [BUGFIX] Include statusMessage intrinsic attribute in tag search. [#3084](https://github.com/grafana/tempo/pull/3084) (@rcrowe)
* [ENHANCEMENT] Update poller to make use of previous results and reduce backend load. [#2652](https://github.com/grafana/tempo/pull/2652) (@zalegrala)
Expand Down
10 changes: 6 additions & 4 deletions modules/overrides/user_configurable_overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

userconfigurableoverrides "github.com/grafana/tempo/modules/overrides/userconfigurable/client"
filterconfig "github.com/grafana/tempo/pkg/spanfilter/config"
"github.com/grafana/tempo/pkg/util/listtomap"
tempo_log "github.com/grafana/tempo/pkg/util/log"
"github.com/grafana/tempo/pkg/util/tracing"
"github.com/grafana/tempo/tempodb/backend"
Expand Down Expand Up @@ -202,10 +203,11 @@ func (o *userConfigurableOverridesManager) Forwarders(userID string) []string {
}

func (o *userConfigurableOverridesManager) MetricsGeneratorProcessors(userID string) map[string]struct{} {
if processors, ok := o.getTenantLimits(userID).GetMetricsGenerator().GetProcessors(); ok {
return processors.GetMap()
}
return o.Interface.MetricsGeneratorProcessors(userID)
// We merge settings from both layers meaning if a processor is enabled on any layer it will be always enabled (OR logic)
processorsUserConfigurable, _ := o.getTenantLimits(userID).GetMetricsGenerator().GetProcessors()
processorsRuntime := o.Interface.MetricsGeneratorProcessors(userID)

return listtomap.Merge(processorsUserConfigurable, processorsRuntime)
}

func (o *userConfigurableOverridesManager) MetricsGeneratorDisableCollection(userID string) bool {
Expand Down
27 changes: 18 additions & 9 deletions modules/overrides/user_configurable_overrides_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@ import (
"time"

"github.com/grafana/dskit/services"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"

userconfigurableoverrides "github.com/grafana/tempo/modules/overrides/userconfigurable/client"
tempo_api "github.com/grafana/tempo/pkg/api"
"github.com/grafana/tempo/pkg/sharedconfig"
filterconfig "github.com/grafana/tempo/pkg/spanfilter/config"
"github.com/grafana/tempo/pkg/util/listtomap"
"github.com/grafana/tempo/tempodb/backend"
"github.com/grafana/tempo/tempodb/backend/local"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
)

const (
Expand Down Expand Up @@ -371,15 +372,24 @@ func TestUserConfigOverridesManager_MergeRuntimeConfig(t *testing.T) {
// Set Forwarders in UserConfigOverrides limits
mgr.tenantLimits[tenantID] = &userconfigurableoverrides.Limits{
Forwarders: &[]string{"my-other-forwarder"},
MetricsGenerator: &userconfigurableoverrides.LimitsMetricsGenerator{
Processors: map[string]struct{}{"local-blocks": {}},
},
}

// test all override methods
// Test all override methods

// Forwarders are set in user-configurable overrides and will override runtime overrides
assert.NotEqual(t, mgr.Forwarders(tenantID), baseMgr.Forwarders(tenantID))

// Processors will be the merged result between runtime and user-configurable overrides
assert.Equal(t, mgr.MetricsGeneratorProcessors(tenantID), map[string]struct{}{"local-blocks": {}, "service-graphs": {}, "span-metrics": {}})

// For the remaining settings runtime overrides will bubble up
assert.Equal(t, mgr.IngestionRateStrategy(), baseMgr.IngestionRateStrategy())
assert.Equal(t, mgr.MaxLocalTracesPerUser(tenantID), baseMgr.MaxLocalTracesPerUser(tenantID))
assert.Equal(t, mgr.MaxGlobalTracesPerUser(tenantID), baseMgr.MaxGlobalTracesPerUser(tenantID))
assert.Equal(t, mgr.MaxBytesPerTrace(tenantID), baseMgr.MaxBytesPerTrace(tenantID))
// Forwarders are set in userconfigurableoverrides so not same as runtime overrides
assert.NotEqual(t, mgr.Forwarders(tenantID), baseMgr.Forwarders(tenantID))
assert.Equal(t, mgr.Forwarders(tenantID), []string{"my-other-forwarder"})
assert.Equal(t, baseMgr.Forwarders(tenantID), []string{"fwd", "fwd-2"})

Expand All @@ -389,7 +399,6 @@ func TestUserConfigOverridesManager_MergeRuntimeConfig(t *testing.T) {
assert.Equal(t, mgr.IngestionBurstSizeBytes(tenantID), baseMgr.IngestionBurstSizeBytes(tenantID))
assert.Equal(t, mgr.MetricsGeneratorIngestionSlack(tenantID), baseMgr.MetricsGeneratorIngestionSlack(tenantID))
assert.Equal(t, mgr.MetricsGeneratorRingSize(tenantID), baseMgr.MetricsGeneratorRingSize(tenantID))
assert.Equal(t, mgr.MetricsGeneratorProcessors(tenantID), baseMgr.MetricsGeneratorProcessors(tenantID))
assert.Equal(t, mgr.MetricsGeneratorMaxActiveSeries(tenantID), baseMgr.MetricsGeneratorMaxActiveSeries(tenantID))
assert.Equal(t, mgr.MetricsGeneratorCollectionInterval(tenantID), baseMgr.MetricsGeneratorCollectionInterval(tenantID))
assert.Equal(t, mgr.MetricsGeneratorDisableCollection(tenantID), baseMgr.MetricsGeneratorDisableCollection(tenantID))
Expand Down
11 changes: 11 additions & 0 deletions pkg/util/listtomap/list_to_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,14 @@ func (l *ListToMap) GetMap() map[string]struct{} {
}
return *l
}

func Merge(m1, m2 ListToMap) ListToMap {
merged := make(ListToMap)
for k := range m1 {
merged[k] = struct{}{}
}
for k := range m2 {
merged[k] = struct{}{}
}
return merged
}
31 changes: 31 additions & 0 deletions pkg/util/listtomap/list_to_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,34 @@ func TestListToMapMarshalOperationsJSON(t *testing.T) {
})
}
}

func TestMerge(t *testing.T) {
testCases := []struct {
name string
m1, m2, merged ListToMap
}{
{
"merge keys from both maps",
map[string]struct{}{"key1": {}, "key3": {}},
map[string]struct{}{"key2": {}, "key3": {}},
map[string]struct{}{"key1": {}, "key2": {}, "key3": {}},
},
{
"nil map",
nil,
map[string]struct{}{"key1": {}},
map[string]struct{}{"key1": {}},
},
{
"both nil",
nil,
nil,
map[string]struct{}{},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.merged, Merge(tc.m1, tc.m2))
})
}
}