Skip to content

Commit 1d452e5

Browse files
authored
[connector/spanmetrics] Deprecate the unused configuration DimensionsCacheSize (#39648)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description fix: #39646
1 parent 556aee3 commit 1d452e5

File tree

10 files changed

+71
-109
lines changed

10 files changed

+71
-109
lines changed

.chloggen/fix-issue-39646.yaml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: deprecation
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: spanmetricsconnector
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Deprecate the unused configuration `dimensions_cache_size`
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [39646]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
Deprecated configuration `dimensions_cache_size`, please use `aggregation_cardinality_limit` instead
20+
21+
# If your change doesn't affect end users or the exported elements of any package,
22+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
23+
# Optional: The change log or logs in which this entry should be included.
24+
# e.g. '[user]' or '[user, api]'
25+
# Include 'user' if the change is relevant to end users.
26+
# Include 'api' if there is a change to a library API.
27+
# Default: '[user]'
28+
change_logs: [user]

connector/spanmetricsconnector/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ The following settings can be optionally configured:
106106

107107
If no `default` is provided, this dimension will be **omitted** from the metric.
108108
- `exclude_dimensions`: the list of dimensions to be excluded from the default set of dimensions. Use to exclude unneeded data from metrics.
109-
- `dimensions_cache_size` (default: `1000`): the size of cache for storing Dimensions to improve collectors memory usage. Must be a positive number.
109+
- `dimensions_cache_size`: this setting is deprecated, please use aggregation_cardinality_limit instead.
110110
- `include_instrumentation_scope`: a list of instrumentation scope names to include from the traces.
111111
- `resource_metrics_cache_size` (default: `1000`): the size of the cache holding metrics for a service. This is mostly relevant for
112112
cumulative temporality to avoid memory leaks and correct metric timestamp resets.

connector/spanmetricsconnector/config.go

+1-7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type Config struct {
4848
// DimensionsCacheSize defines the size of cache for storing Dimensions, which helps to avoid cache memory growing
4949
// indefinitely over the lifetime of the collector.
5050
// Optional. See defaultDimensionsCacheSize in connector.go for the default value.
51+
// Deprecated: Please use AggregationCardinalityLimit instead
5152
DimensionsCacheSize int `mapstructure:"dimensions_cache_size"`
5253

5354
// ResourceMetricsCacheSize defines the size of the cache holding metrics for a service. This is mostly relevant for
@@ -133,13 +134,6 @@ func (c Config) Validate() error {
133134
return fmt.Errorf("failed validating event dimensions: %w", err)
134135
}
135136

136-
if c.DimensionsCacheSize <= 0 {
137-
return fmt.Errorf(
138-
"invalid cache size: %v, the maximum number of the items in the cache should be positive",
139-
c.DimensionsCacheSize,
140-
)
141-
}
142-
143137
if c.Histogram.Explicit != nil && c.Histogram.Exponential != nil {
144138
return errors.New("use either `explicit` or `exponential` buckets histogram")
145139
}

connector/spanmetricsconnector/config_test.go

-24
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ func TestLoadConfig(t *testing.T) {
5353
{Name: "http.status_code", Default: (*string)(nil)},
5454
},
5555
Namespace: DefaultNamespace,
56-
DimensionsCacheSize: 1500,
5756
ResourceMetricsCacheSize: 1600,
5857
MetricsFlushInterval: 30 * time.Second,
5958
Exemplars: ExemplarsConfig{
@@ -76,7 +75,6 @@ func TestLoadConfig(t *testing.T) {
7675
expected: &Config{
7776
Namespace: DefaultNamespace,
7877
AggregationTemporality: cumulative,
79-
DimensionsCacheSize: defaultDimensionsCacheSize,
8078
ResourceMetricsCacheSize: defaultResourceMetricsCacheSize,
8179
MetricsFlushInterval: 60 * time.Second,
8280
Histogram: HistogramConfig{
@@ -103,7 +101,6 @@ func TestLoadConfig(t *testing.T) {
103101
id: component.NewIDWithName(metadata.Type, "exemplars_enabled"),
104102
expected: &Config{
105103
AggregationTemporality: "AGGREGATION_TEMPORALITY_CUMULATIVE",
106-
DimensionsCacheSize: defaultDimensionsCacheSize,
107104
ResourceMetricsCacheSize: defaultResourceMetricsCacheSize,
108105
MetricsFlushInterval: 60 * time.Second,
109106
Histogram: HistogramConfig{Disable: false, Unit: defaultUnit},
@@ -115,7 +112,6 @@ func TestLoadConfig(t *testing.T) {
115112
id: component.NewIDWithName(metadata.Type, "exemplars_enabled_with_max_per_datapoint"),
116113
expected: &Config{
117114
AggregationTemporality: "AGGREGATION_TEMPORALITY_CUMULATIVE",
118-
DimensionsCacheSize: defaultDimensionsCacheSize,
119115
ResourceMetricsCacheSize: defaultResourceMetricsCacheSize,
120116
MetricsFlushInterval: 60 * time.Second,
121117
Histogram: HistogramConfig{Disable: false, Unit: defaultUnit},
@@ -127,7 +123,6 @@ func TestLoadConfig(t *testing.T) {
127123
id: component.NewIDWithName(metadata.Type, "resource_metrics_key_attributes"),
128124
expected: &Config{
129125
AggregationTemporality: "AGGREGATION_TEMPORALITY_CUMULATIVE",
130-
DimensionsCacheSize: defaultDimensionsCacheSize,
131126
ResourceMetricsCacheSize: defaultResourceMetricsCacheSize,
132127
ResourceMetricsKeyAttributes: []string{"service.name", "telemetry.sdk.language", "telemetry.sdk.name"},
133128
MetricsFlushInterval: 60 * time.Second,
@@ -140,7 +135,6 @@ func TestLoadConfig(t *testing.T) {
140135
expected: &Config{
141136
AggregationTemporality: "AGGREGATION_TEMPORALITY_DELTA",
142137
TimestampCacheSize: &customTimestampCacheSize,
143-
DimensionsCacheSize: defaultDimensionsCacheSize,
144138
ResourceMetricsCacheSize: defaultResourceMetricsCacheSize,
145139
MetricsFlushInterval: 60 * time.Second,
146140
Histogram: HistogramConfig{Disable: false, Unit: defaultUnit},
@@ -151,7 +145,6 @@ func TestLoadConfig(t *testing.T) {
151145
id: component.NewIDWithName(metadata.Type, "default_delta_timestamp_cache_size"),
152146
expected: &Config{
153147
AggregationTemporality: "AGGREGATION_TEMPORALITY_DELTA",
154-
DimensionsCacheSize: defaultDimensionsCacheSize,
155148
ResourceMetricsCacheSize: defaultResourceMetricsCacheSize,
156149
MetricsFlushInterval: 60 * time.Second,
157150
Histogram: HistogramConfig{Disable: false, Unit: defaultUnit},
@@ -298,7 +291,6 @@ func TestConfigValidate(t *testing.T) {
298291
{
299292
name: "valid config",
300293
config: Config{
301-
DimensionsCacheSize: 1000,
302294
ResourceMetricsCacheSize: 1000,
303295
MetricsFlushInterval: 60 * time.Second,
304296
Histogram: HistogramConfig{
@@ -308,19 +300,9 @@ func TestConfigValidate(t *testing.T) {
308300
},
309301
},
310302
},
311-
{
312-
name: "invalid dimensions cache size",
313-
config: Config{
314-
DimensionsCacheSize: -1,
315-
ResourceMetricsCacheSize: 1000,
316-
MetricsFlushInterval: 60 * time.Second,
317-
},
318-
expectedErr: "invalid cache size: -1, the maximum number of the items in the cache should be positive",
319-
},
320303
{
321304
name: "invalid metrics flush interval",
322305
config: Config{
323-
DimensionsCacheSize: 1000,
324306
ResourceMetricsCacheSize: 1000,
325307
MetricsFlushInterval: -1 * time.Second,
326308
},
@@ -329,7 +311,6 @@ func TestConfigValidate(t *testing.T) {
329311
{
330312
name: "invalid metrics expiration",
331313
config: Config{
332-
DimensionsCacheSize: 1000,
333314
ResourceMetricsCacheSize: 1000,
334315
MetricsFlushInterval: 60 * time.Second,
335316
MetricsExpiration: -1 * time.Second,
@@ -339,7 +320,6 @@ func TestConfigValidate(t *testing.T) {
339320
{
340321
name: "invalid delta timestamp cache size",
341322
config: Config{
342-
DimensionsCacheSize: 1000,
343323
ResourceMetricsCacheSize: 1000,
344324
MetricsFlushInterval: 60 * time.Second,
345325
AggregationTemporality: delta,
@@ -350,7 +330,6 @@ func TestConfigValidate(t *testing.T) {
350330
{
351331
name: "invalid aggregation cardinality limit",
352332
config: Config{
353-
DimensionsCacheSize: 1000,
354333
ResourceMetricsCacheSize: 1000,
355334
MetricsFlushInterval: 60 * time.Second,
356335
AggregationCardinalityLimit: -1,
@@ -360,7 +339,6 @@ func TestConfigValidate(t *testing.T) {
360339
{
361340
name: "both explicit and exponential histogram",
362341
config: Config{
363-
DimensionsCacheSize: 1000,
364342
ResourceMetricsCacheSize: 1000,
365343
MetricsFlushInterval: 60 * time.Second,
366344
Histogram: HistogramConfig{
@@ -377,7 +355,6 @@ func TestConfigValidate(t *testing.T) {
377355
{
378356
name: "duplicate dimension name",
379357
config: Config{
380-
DimensionsCacheSize: 1000,
381358
ResourceMetricsCacheSize: 1000,
382359
MetricsFlushInterval: 60 * time.Second,
383360
Dimensions: []Dimension{
@@ -389,7 +366,6 @@ func TestConfigValidate(t *testing.T) {
389366
{
390367
name: "events enabled with no dimensions",
391368
config: Config{
392-
DimensionsCacheSize: 1000,
393369
ResourceMetricsCacheSize: 1000,
394370
MetricsFlushInterval: 60 * time.Second,
395371
Events: EventsConfig{

connector/spanmetricsconnector/connector.go

+28-36
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ const (
3636
instrumentationScopeVersionKey = "span.instrumentation.scope.version" // OpenTelemetry non-standard constant.
3737
metricKeySeparator = string(byte(0))
3838

39-
defaultDimensionsCacheSize = 1000
4039
defaultResourceMetricsCacheSize = 1000
4140

4241
metricNameDuration = "duration"
@@ -65,10 +64,6 @@ type connectorImp struct {
6564

6665
keyBuf *bytes.Buffer
6766

68-
// An LRU cache of dimension key-value maps keyed by a unique identifier formed by a concatenation of its values:
69-
// e.g. { "foo/barOK": { "serviceName": "foo", "span.name": "/bar", "status_code": "OK" }}
70-
metricKeyToDimensions *cache.Cache[metrics.Key, pcommon.Map]
71-
7267
clock clockwork.Clock
7368
ticker clockwork.Ticker
7469
done chan struct{}
@@ -112,10 +107,8 @@ func newDimensions(cfgDims []Dimension) []utilattri.Dimension {
112107
func newConnector(logger *zap.Logger, config component.Config, clock clockwork.Clock) (*connectorImp, error) {
113108
logger.Info("Building spanmetrics connector")
114109
cfg := config.(*Config)
115-
116-
metricKeyToDimensionsCache, err := cache.NewCache[metrics.Key, pcommon.Map](cfg.DimensionsCacheSize)
117-
if err != nil {
118-
return nil, err
110+
if cfg.DimensionsCacheSize != 0 {
111+
logger.Warn("DimensionsCacheSize is deprecated, please use AggregationCardinalityLimit instead.")
119112
}
120113

121114
resourceMetricsCache, err := cache.NewCache[resourceKey, *resourceMetrics](cfg.ResourceMetricsCacheSize)
@@ -146,7 +139,6 @@ func newConnector(logger *zap.Logger, config component.Config, clock clockwork.C
146139
resourceMetricsKeyAttributes: resourceMetricsKeyAttributes,
147140
dimensions: newDimensions(cfg.Dimensions),
148141
keyBuf: bytes.NewBuffer(make([]byte, 0, 1024)),
149-
metricKeyToDimensions: metricKeyToDimensionsCache,
150142
lastDeltaTimestamps: lastDeltaTimestamps,
151143
clock: clock,
152144
ticker: clock.NewTicker(cfg.MetricsFlushInterval),
@@ -331,10 +323,8 @@ func (p *connectorImp) resetState() {
331323
// If delta metrics, reset accumulated data
332324
if p.config.GetAggregationTemporality() == pmetric.AggregationTemporalityDelta {
333325
p.resourceMetrics.Purge()
334-
p.metricKeyToDimensions.Purge()
335326
} else {
336327
p.resourceMetrics.RemoveEvictedItems()
337-
p.metricKeyToDimensions.RemoveEvictedItems()
338328

339329
// If none of these features are enabled then we can skip the remaining operations.
340330
// Enabling either of these features requires to go over resource metrics and do operation on each.
@@ -399,43 +389,45 @@ func (p *connectorImp) aggregateMetrics(traces ptrace.Traces) {
399389
if endTime > startTime {
400390
duration = float64(endTime-startTime) / float64(unitDivider)
401391
}
402-
key := p.buildKey(serviceName, span, p.dimensions, resourceAttr)
403392

404-
var attributes pcommon.Map
393+
key := p.buildKey(serviceName, span, p.dimensions, resourceAttr)
394+
var attributesFun metrics.BuildAttributesFun
405395

406396
// Note: we check cardinality limit here for sums metrics but it is the same
407397
// for histograms because both use the same key and attributes.
408398
if rm.sums.IsCardinalityLimitReached() {
409-
attributes = pcommon.NewMap()
410-
for _, d := range p.dimensions {
411-
if v, exists := utilattri.GetDimensionValue(d, span.Attributes(), resourceAttr); exists {
412-
v.CopyTo(attributes.PutEmpty(d.Name))
399+
attributesFun = func() pcommon.Map {
400+
attributes := pcommon.NewMap()
401+
for _, d := range p.dimensions {
402+
if v, exists := utilattri.GetDimensionValue(d, span.Attributes(), resourceAttr); exists {
403+
v.CopyTo(attributes.PutEmpty(d.Name))
404+
}
413405
}
406+
attributes.PutBool(overflowKey, true)
407+
408+
return attributes
414409
}
415-
attributes.PutBool(overflowKey, true)
416410
} else {
417-
var cached bool
418-
attributes, cached = p.metricKeyToDimensions.Get(key)
419-
if !cached {
420-
attributes = p.buildAttributes(
411+
attributesFun = func() pcommon.Map {
412+
attributes := p.buildAttributes(
421413
serviceName,
422414
span,
423415
resourceAttr,
424416
p.dimensions,
425417
ils.Scope(),
426418
)
427-
p.metricKeyToDimensions.Add(key, attributes)
419+
return attributes
428420
}
429421
}
430422

431423
if !p.config.Histogram.Disable {
432424
// aggregate histogram metrics
433-
h := histograms.GetOrCreate(key, attributes, startTimestamp)
425+
h := histograms.GetOrCreate(key, attributesFun, startTimestamp)
434426
p.addExemplar(span, duration, h)
435427
h.Observe(duration)
436428
}
437429
// aggregate sums metrics
438-
s := sums.GetOrCreate(key, attributes, startTimestamp)
430+
s := sums.GetOrCreate(key, attributesFun, startTimestamp)
439431
if p.config.Exemplars.Enabled && !span.TraceID().IsEmpty() {
440432
s.AddExemplar(span.TraceID(), span.SpanID(), duration)
441433
}
@@ -459,20 +451,20 @@ func (p *connectorImp) aggregateMetrics(traces ptrace.Traces) {
459451
})
460452

461453
eKey := p.buildKey(serviceName, span, eDimensions, rscAndEventAttrs)
462-
463-
var eAttributes pcommon.Map
464454
if rm.events.IsCardinalityLimitReached() {
465-
eAttributes = pcommon.NewMap()
466-
rscAndEventAttrs.CopyTo(eAttributes)
467-
eAttributes.PutBool(overflowKey, true)
455+
attributesFun = func() pcommon.Map {
456+
attributes := pcommon.NewMap()
457+
rscAndEventAttrs.CopyTo(attributes)
458+
attributes.PutBool(overflowKey, true)
459+
460+
return attributes
461+
}
468462
} else {
469-
eAttributes, ok = p.metricKeyToDimensions.Get(eKey)
470-
if !ok {
471-
eAttributes = p.buildAttributes(serviceName, span, rscAndEventAttrs, eDimensions, ils.Scope())
472-
p.metricKeyToDimensions.Add(eKey, eAttributes)
463+
attributesFun = func() pcommon.Map {
464+
return p.buildAttributes(serviceName, span, rscAndEventAttrs, eDimensions, ils.Scope())
473465
}
474466
}
475-
e := events.GetOrCreate(eKey, eAttributes, startTimestamp)
467+
e := events.GetOrCreate(eKey, attributesFun, startTimestamp)
476468
if p.config.Exemplars.Enabled && !span.TraceID().IsEmpty() {
477469
e.AddExemplar(span.TraceID(), span.SpanID(), duration)
478470
}

connector/spanmetricsconnector/connector_test.go

-31
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ const (
4646
notInSpanAttrName1 = "shouldNotBeInMetric"
4747
regionResourceAttrName = "region"
4848
exceptionTypeAttrName = "exception.type"
49-
dimensionsCacheSize = 2
5049
resourceMetricsCacheSize = 5
5150

5251
sampleRegion = "us-east-1"
@@ -465,7 +464,6 @@ func newConnectorImp(defaultNullValue *string, histogramConfig func() HistogramC
465464
Histogram: histogramConfig(),
466465
Exemplars: exemplarsConfig(),
467466
ExcludeDimensions: excludedDimensions,
468-
DimensionsCacheSize: dimensionsCacheSize,
469467
ResourceMetricsCacheSize: resourceMetricsCacheSize,
470468
ResourceMetricsKeyAttributes: resourceMetricsKeyAttributes,
471469
Dimensions: []Dimension{
@@ -914,35 +912,6 @@ func TestConsumeTraces(t *testing.T) {
914912
}
915913
}
916914

917-
func TestMetricKeyCache(t *testing.T) {
918-
p, err := newConnectorImp(stringp("defaultNullValue"), explicitHistogramsConfig, disabledExemplarsConfig, disabledEventsConfig, cumulative, 0, []string{}, 1000, clockwork.NewFakeClock())
919-
require.NoError(t, err)
920-
traces := buildSampleTrace()
921-
922-
// Test
923-
ctx := metadata.NewIncomingContext(context.Background(), nil)
924-
925-
// 0 key was cached at beginning
926-
assert.Zero(t, p.metricKeyToDimensions.Len())
927-
928-
err = p.ConsumeTraces(ctx, traces)
929-
// Validate
930-
require.NoError(t, err)
931-
// 2 key was cached, 1 key was evicted and cleaned after the processing
932-
assert.Eventually(t, func() bool {
933-
return p.metricKeyToDimensions.Len() == dimensionsCacheSize
934-
}, 10*time.Second, time.Millisecond*100)
935-
936-
// consume another batch of traces
937-
err = p.ConsumeTraces(ctx, traces)
938-
require.NoError(t, err)
939-
940-
// 2 key was cached, other keys were evicted and cleaned after the processing
941-
assert.Eventually(t, func() bool {
942-
return p.metricKeyToDimensions.Len() == dimensionsCacheSize
943-
}, 10*time.Second, time.Millisecond*100)
944-
}
945-
946915
func TestResourceMetricsCache(t *testing.T) {
947916
p, err := newConnectorImp(stringp("defaultNullValue"), explicitHistogramsConfig, disabledExemplarsConfig, disabledEventsConfig, cumulative, 0, []string{}, 1000, clockwork.NewFakeClock())
948917
require.NoError(t, err)

connector/spanmetricsconnector/factory.go

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ func NewFactory() connector.Factory {
4747
func createDefaultConfig() component.Config {
4848
return &Config{
4949
AggregationTemporality: "AGGREGATION_TEMPORALITY_CUMULATIVE",
50-
DimensionsCacheSize: defaultDimensionsCacheSize,
5150
ResourceMetricsCacheSize: defaultResourceMetricsCacheSize,
5251
MetricsFlushInterval: 60 * time.Second,
5352
Histogram: HistogramConfig{Disable: false, Unit: defaultUnit},

0 commit comments

Comments
 (0)