diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index f5880ce3ae..abb71fc186 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -5,6 +5,8 @@ - Fix SimpleSpanProcessor to be consistent with log counterpart. Also removed dependency on crossbeam-channel. [1612](https://github.com/open-telemetry/opentelemetry-rust/pull/1612/files) +- [#1422](https://github.com/open-telemetry/opentelemetry-rust/pull/1422) + Fix metrics aggregation bug when using Views to drop attributes. ## v0.22.1 diff --git a/opentelemetry-sdk/src/attributes/set.rs b/opentelemetry-sdk/src/attributes/set.rs index ae5d5a4a73..743ac49fe7 100644 --- a/opentelemetry-sdk/src/attributes/set.rs +++ b/opentelemetry-sdk/src/attributes/set.rs @@ -138,16 +138,20 @@ impl From<&Resource> for AttributeSet { } } +fn calculate_hash(values: &[HashKeyValue]) -> u64 { + let mut hasher = DefaultHasher::new(); + values.iter().fold(&mut hasher, |mut hasher, item| { + item.hash(&mut hasher); + hasher + }); + hasher.finish() +} + impl AttributeSet { fn new(mut values: Vec) -> Self { values.sort_unstable(); - let mut hasher = DefaultHasher::new(); - values.iter().fold(&mut hasher, |mut hasher, item| { - item.hash(&mut hasher); - hasher - }); - - AttributeSet(values, hasher.finish()) + let hash = calculate_hash(&values); + AttributeSet(values, hash) } /// Returns the number of elements in the set. @@ -165,7 +169,10 @@ impl AttributeSet { where F: Fn(&KeyValue) -> bool, { - self.0.retain(|kv| f(&kv.0)) + self.0.retain(|kv| f(&kv.0)); + + // Recalculate the hash as elements are changed. + self.1 = calculate_hash(&self.0); } /// Iterate over key value pairs in the set diff --git a/opentelemetry-sdk/src/metrics/mod.rs b/opentelemetry-sdk/src/metrics/mod.rs index 50673f7d25..80ff89469b 100644 --- a/opentelemetry-sdk/src/metrics/mod.rs +++ b/opentelemetry-sdk/src/metrics/mod.rs @@ -532,7 +532,6 @@ mod tests { // "multi_thread" tokio flavor must be used else flush won't // be able to make progress! #[tokio::test(flavor = "multi_thread", worker_threads = 1)] - #[ignore = "Spatial aggregation is not yet implemented."] async fn spatial_aggregation_when_view_drops_attributes_counter() { // cargo test spatial_aggregation_when_view_drops_attributes_counter --features=metrics,testing