Skip to content

Commit 4be1a32

Browse files
authored
fix: remove cardinality capping via instrument advice (#2995)
1 parent 3d04c16 commit 4be1a32

File tree

6 files changed

+5
-159
lines changed

6 files changed

+5
-159
lines changed

opentelemetry-sdk/CHANGELOG.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ also modified to suppress telemetry before invoking exporters.
2121
- The default cardinality limit is 2000 and can be customized using Views.
2222
- This feature was previously removed in version 0.28 due to the lack of
2323
configurability but has now been reintroduced with the ability to configure
24-
the limit.
25-
- There is ability to configure cardinality limits via Instrument
26-
advisory. [#2903](https://github.com/open-telemetry/opentelemetry-rust/pull/2903)
24+
the limit.
2725
- Fixed the overflow attribute to correctly use the boolean value `true`
2826
instead of the string `"true"`.
2927
[#2878](https://github.com/open-telemetry/opentelemetry-rust/issues/2878)

opentelemetry-sdk/src/metrics/meter.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ impl SdkMeter {
9696
builder.description,
9797
builder.unit,
9898
None,
99-
builder.cardinality_limit,
10099
)
101100
.map(|i| Counter::new(Arc::new(i)))
102101
{
@@ -139,7 +138,6 @@ impl SdkMeter {
139138
builder.description,
140139
builder.unit,
141140
None,
142-
builder.cardinality_limit,
143141
) {
144142
Ok(ms) => {
145143
if ms.is_empty() {
@@ -199,7 +197,6 @@ impl SdkMeter {
199197
builder.description,
200198
builder.unit,
201199
None,
202-
builder.cardinality_limit,
203200
) {
204201
Ok(ms) => {
205202
if ms.is_empty() {
@@ -259,7 +256,6 @@ impl SdkMeter {
259256
builder.description,
260257
builder.unit,
261258
None,
262-
builder.cardinality_limit,
263259
) {
264260
Ok(ms) => {
265261
if ms.is_empty() {
@@ -321,7 +317,6 @@ impl SdkMeter {
321317
builder.description,
322318
builder.unit,
323319
None,
324-
builder.cardinality_limit,
325320
)
326321
.map(|i| UpDownCounter::new(Arc::new(i)))
327322
{
@@ -366,7 +361,6 @@ impl SdkMeter {
366361
builder.description,
367362
builder.unit,
368363
None,
369-
builder.cardinality_limit,
370364
)
371365
.map(|i| Gauge::new(Arc::new(i)))
372366
{
@@ -428,7 +422,6 @@ impl SdkMeter {
428422
builder.description,
429423
builder.unit,
430424
builder.boundaries,
431-
builder.cardinality_limit,
432425
)
433426
.map(|i| Histogram::new(Arc::new(i)))
434427
{
@@ -661,10 +654,8 @@ where
661654
description: Option<Cow<'static, str>>,
662655
unit: Option<Cow<'static, str>>,
663656
boundaries: Option<Vec<f64>>,
664-
cardinality_limit: Option<usize>,
665657
) -> MetricResult<ResolvedMeasures<T>> {
666-
let aggregators =
667-
self.measures(kind, name, description, unit, boundaries, cardinality_limit)?;
658+
let aggregators = self.measures(kind, name, description, unit, boundaries)?;
668659
Ok(ResolvedMeasures {
669660
measures: aggregators,
670661
})
@@ -677,7 +668,6 @@ where
677668
description: Option<Cow<'static, str>>,
678669
unit: Option<Cow<'static, str>>,
679670
boundaries: Option<Vec<f64>>,
680-
cardinality_limit: Option<usize>,
681671
) -> MetricResult<Vec<Arc<dyn internal::Measure<T>>>> {
682672
let inst = Instrument {
683673
name,
@@ -687,7 +677,7 @@ where
687677
scope: self.meter.scope.clone(),
688678
};
689679

690-
self.resolve.measures(inst, boundaries, cardinality_limit)
680+
self.resolve.measures(inst, boundaries)
691681
}
692682
}
693683

opentelemetry-sdk/src/metrics/mod.rs

Lines changed: 0 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -369,14 +369,12 @@ mod tests {
369369
async fn counter_aggregation_overflow_delta() {
370370
counter_aggregation_overflow_helper(Temporality::Delta);
371371
counter_aggregation_overflow_helper_custom_limit(Temporality::Delta);
372-
counter_aggregation_overflow_helper_custom_limit_via_advice(Temporality::Delta);
373372
}
374373

375374
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
376375
async fn counter_aggregation_overflow_cumulative() {
377376
counter_aggregation_overflow_helper(Temporality::Cumulative);
378377
counter_aggregation_overflow_helper_custom_limit(Temporality::Cumulative);
379-
counter_aggregation_overflow_helper_custom_limit_via_advice(Temporality::Cumulative);
380378
}
381379

382380
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
@@ -2955,103 +2953,6 @@ mod tests {
29552953
}
29562954
}
29572955

2958-
fn counter_aggregation_overflow_helper_custom_limit_via_advice(temporality: Temporality) {
2959-
// Arrange
2960-
let cardinality_limit = 2300;
2961-
let mut test_context = TestContext::new(temporality);
2962-
let meter = test_context.meter();
2963-
let counter = meter
2964-
.u64_counter("my_counter")
2965-
.with_cardinality_limit(cardinality_limit)
2966-
.build();
2967-
2968-
// Act
2969-
// Record measurements with A:0, A:1,.......A:cardinality_limit, which just fits in the cardinality_limit
2970-
for v in 0..cardinality_limit {
2971-
counter.add(100, &[KeyValue::new("A", v.to_string())]);
2972-
}
2973-
2974-
// Empty attributes is specially treated and does not count towards the limit.
2975-
counter.add(3, &[]);
2976-
counter.add(3, &[]);
2977-
2978-
// All of the below will now go into overflow.
2979-
counter.add(100, &[KeyValue::new("A", "foo")]);
2980-
counter.add(100, &[KeyValue::new("A", "another")]);
2981-
counter.add(100, &[KeyValue::new("A", "yet_another")]);
2982-
test_context.flush_metrics();
2983-
2984-
let MetricData::Sum(sum) = test_context.get_aggregation::<u64>("my_counter", None) else {
2985-
unreachable!()
2986-
};
2987-
2988-
// Expecting (cardinality_limit + 1 overflow + Empty attributes) data points.
2989-
assert_eq!(sum.data_points.len(), cardinality_limit + 1 + 1);
2990-
2991-
let data_point =
2992-
find_overflow_sum_datapoint(&sum.data_points).expect("overflow point expected");
2993-
assert_eq!(data_point.value, 300);
2994-
2995-
// let empty_attrs_data_point = &sum.data_points[0];
2996-
let empty_attrs_data_point = find_sum_datapoint_with_no_attributes(&sum.data_points)
2997-
.expect("Empty attributes point expected");
2998-
assert!(
2999-
empty_attrs_data_point.attributes.is_empty(),
3000-
"Non-empty attribute set"
3001-
);
3002-
assert_eq!(
3003-
empty_attrs_data_point.value, 6,
3004-
"Empty attributes value should be 3+3=6"
3005-
);
3006-
3007-
// Phase 2 - for delta temporality, after each collect, data points are cleared
3008-
// but for cumulative, they are not cleared.
3009-
test_context.reset_metrics();
3010-
// The following should be aggregated normally for Delta,
3011-
// and should go into overflow for Cumulative.
3012-
counter.add(100, &[KeyValue::new("A", "foo")]);
3013-
counter.add(100, &[KeyValue::new("A", "another")]);
3014-
counter.add(100, &[KeyValue::new("A", "yet_another")]);
3015-
test_context.flush_metrics();
3016-
3017-
let MetricData::Sum(sum) = test_context.get_aggregation::<u64>("my_counter", None) else {
3018-
unreachable!()
3019-
};
3020-
3021-
if temporality == Temporality::Delta {
3022-
assert_eq!(sum.data_points.len(), 3);
3023-
3024-
let data_point = find_sum_datapoint_with_key_value(&sum.data_points, "A", "foo")
3025-
.expect("point expected");
3026-
assert_eq!(data_point.value, 100);
3027-
3028-
let data_point = find_sum_datapoint_with_key_value(&sum.data_points, "A", "another")
3029-
.expect("point expected");
3030-
assert_eq!(data_point.value, 100);
3031-
3032-
let data_point =
3033-
find_sum_datapoint_with_key_value(&sum.data_points, "A", "yet_another")
3034-
.expect("point expected");
3035-
assert_eq!(data_point.value, 100);
3036-
} else {
3037-
// For cumulative, overflow should still be there, and new points should not be added.
3038-
assert_eq!(sum.data_points.len(), cardinality_limit + 1 + 1);
3039-
let data_point =
3040-
find_overflow_sum_datapoint(&sum.data_points).expect("overflow point expected");
3041-
assert_eq!(data_point.value, 600);
3042-
3043-
let data_point = find_sum_datapoint_with_key_value(&sum.data_points, "A", "foo");
3044-
assert!(data_point.is_none(), "point should not be present");
3045-
3046-
let data_point = find_sum_datapoint_with_key_value(&sum.data_points, "A", "another");
3047-
assert!(data_point.is_none(), "point should not be present");
3048-
3049-
let data_point =
3050-
find_sum_datapoint_with_key_value(&sum.data_points, "A", "yet_another");
3051-
assert!(data_point.is_none(), "point should not be present");
3052-
}
3053-
}
3054-
30552956
fn counter_aggregation_attribute_order_helper(temporality: Temporality, start_sorted: bool) {
30562957
// Arrange
30572958
let mut test_context = TestContext::new(temporality);

opentelemetry-sdk/src/metrics/pipeline.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,6 @@ where
254254
&self,
255255
inst: Instrument,
256256
boundaries: Option<&[f64]>,
257-
cardinality_limit: Option<usize>,
258257
) -> MetricResult<Vec<Arc<dyn internal::Measure<T>>>> {
259258
let mut matched = false;
260259
let mut measures = vec![];
@@ -312,7 +311,7 @@ where
312311
unit: Some(inst.unit),
313312
aggregation: None,
314313
allowed_attribute_keys: None,
315-
cardinality_limit,
314+
cardinality_limit: None,
316315
};
317316

318317
// Override default histogram boundaries if provided.
@@ -737,12 +736,11 @@ where
737736
&self,
738737
id: Instrument,
739738
boundaries: Option<Vec<f64>>,
740-
cardinality_limit: Option<usize>,
741739
) -> MetricResult<Vec<Arc<dyn internal::Measure<T>>>> {
742740
let (mut measures, mut errs) = (vec![], vec![]);
743741

744742
for inserter in &self.inserters {
745-
match inserter.instrument(id.clone(), boundaries.as_deref(), cardinality_limit) {
743+
match inserter.instrument(id.clone(), boundaries.as_deref()) {
746744
Ok(ms) => measures.extend(ms),
747745
Err(err) => errs.push(err),
748746
}

opentelemetry/CHANGELOG.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ disable telemetry generation during their internal operations, ensuring more
2424
predictable and efficient observability pipelines.
2525

2626
- re-export `tracing` for `internal-logs` feature to remove the need of adding `tracing` as a dependency
27-
- Added ability to configure cardinality limits via Instrument
28-
advisory. [#2903](https://github.com/open-telemetry/opentelemetry-rust/pull/2903)
2927

3028
## 0.29.1
3129

opentelemetry/src/metrics/instruments/mod.rs

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ pub struct HistogramBuilder<'a, T> {
4545
/// Unit of the Histogram.
4646
pub unit: Option<Cow<'static, str>>,
4747

48-
/// Cardinality limit for the Histogram.
49-
pub cardinality_limit: Option<usize>,
50-
5148
/// Bucket boundaries for the histogram.
5249
pub boundaries: Option<Vec<f64>>,
5350

@@ -63,7 +60,6 @@ impl<'a, T> HistogramBuilder<'a, T> {
6360
name,
6461
description: None,
6562
unit: None,
66-
cardinality_limit: None,
6763
boundaries: None,
6864
_marker: marker::PhantomData,
6965
}
@@ -87,14 +83,6 @@ impl<'a, T> HistogramBuilder<'a, T> {
8783
self
8884
}
8985

90-
/// Set the cardinality limit for this Histogram.
91-
/// Setting cardinality limit is optional. By default, the limit will be set
92-
/// to 2000.
93-
pub fn with_cardinality_limit(mut self, limit: usize) -> Self {
94-
self.cardinality_limit = Some(limit);
95-
self
96-
}
97-
9886
/// Set the boundaries for this histogram.
9987
///
10088
/// Setting boundaries is optional. By default, the boundaries are set to:
@@ -162,9 +150,6 @@ pub struct InstrumentBuilder<'a, T> {
162150
/// Unit of the instrument.
163151
pub unit: Option<Cow<'static, str>>,
164152

165-
/// Cardinality limit for the instrument.
166-
pub cardinality_limit: Option<usize>,
167-
168153
_marker: marker::PhantomData<T>,
169154
}
170155

@@ -176,7 +161,6 @@ impl<'a, T> InstrumentBuilder<'a, T> {
176161
name,
177162
description: None,
178163
unit: None,
179-
cardinality_limit: None,
180164
_marker: marker::PhantomData,
181165
}
182166
}
@@ -198,14 +182,6 @@ impl<'a, T> InstrumentBuilder<'a, T> {
198182
self.unit = Some(unit.into());
199183
self
200184
}
201-
202-
/// Set the cardinality limit for this instrument.
203-
/// Setting cardinality limit is optional. By default, the limit will be set
204-
/// to 2000.
205-
pub fn with_cardinality_limit(mut self, limit: usize) -> Self {
206-
self.cardinality_limit = Some(limit);
207-
self
208-
}
209185
}
210186

211187
macro_rules! build_instrument {
@@ -235,7 +211,6 @@ impl<T> fmt::Debug for InstrumentBuilder<'_, T> {
235211
.field("name", &self.name)
236212
.field("description", &self.description)
237213
.field("unit", &self.unit)
238-
.field("cardinality_limit", &self.cardinality_limit)
239214
.field("kind", &std::any::type_name::<T>())
240215
.finish()
241216
}
@@ -247,7 +222,6 @@ impl<T> fmt::Debug for HistogramBuilder<'_, T> {
247222
.field("name", &self.name)
248223
.field("description", &self.description)
249224
.field("unit", &self.unit)
250-
.field("cardinality_limit", &self.cardinality_limit)
251225
.field("boundaries", &self.boundaries)
252226
.field(
253227
"kind",
@@ -281,9 +255,6 @@ pub struct AsyncInstrumentBuilder<'a, I, M> {
281255
/// Unit of the instrument.
282256
pub unit: Option<Cow<'static, str>>,
283257

284-
/// Cardinality limit for the instrument.
285-
pub cardinality_limit: Option<usize>,
286-
287258
/// Callbacks to be called for this instrument.
288259
pub callbacks: Vec<Callback<M>>,
289260

@@ -298,7 +269,6 @@ impl<'a, I, M> AsyncInstrumentBuilder<'a, I, M> {
298269
name,
299270
description: None,
300271
unit: None,
301-
cardinality_limit: None,
302272
_inst: marker::PhantomData,
303273
callbacks: Vec::new(),
304274
}
@@ -322,14 +292,6 @@ impl<'a, I, M> AsyncInstrumentBuilder<'a, I, M> {
322292
self
323293
}
324294

325-
/// Set the cardinality limit for this async instrument.
326-
/// Setting cardinality limit is optional. By default, the limit will be set
327-
/// to 2000.
328-
pub fn with_cardinality_limit(mut self, limit: usize) -> Self {
329-
self.cardinality_limit = Some(limit);
330-
self
331-
}
332-
333295
/// Set the callback to be called for this instrument.
334296
pub fn with_callback<F>(mut self, callback: F) -> Self
335297
where
@@ -378,7 +340,6 @@ where
378340
.field("name", &self.name)
379341
.field("description", &self.description)
380342
.field("unit", &self.unit)
381-
.field("cardinality_limit", &self.cardinality_limit)
382343
.field("kind", &std::any::type_name::<I>())
383344
.field("callbacks_len", &self.callbacks.len())
384345
.finish()

0 commit comments

Comments
 (0)