From eeeaccec81ccc2922accbe6856b0164420e5fbdf Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 2 Jan 2024 19:14:05 +0000 Subject: [PATCH 1/5] fix attribute processor --- .../sdk/metrics/data/exemplar_data.h | 4 +- .../sdk/metrics/exemplar/filter.h | 4 +- .../opentelemetry/sdk/metrics/instruments.h | 4 +- .../sdk/metrics/state/attributes_hashmap.h | 12 ++++-- .../state/filtered_ordered_attribute_map.h | 39 +++++++++++++++++ .../sdk/metrics/state/sync_metric_storage.h | 6 ++- .../sdk/metrics/view/attributes_processor.h | 5 ++- sdk/src/metrics/CMakeLists.txt | 1 + .../state/filtered_ordered_attribute_map.cc | 43 +++++++++++++++++++ 9 files changed, 105 insertions(+), 13 deletions(-) create mode 100644 sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h create mode 100644 sdk/src/metrics/state/filtered_ordered_attribute_map.cc diff --git a/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h b/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h index efad19b098..59097185ee 100644 --- a/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h +++ b/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h @@ -6,8 +6,8 @@ #include #include "opentelemetry/common/timestamp.h" -#include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/sdk/metrics/data/metric_data.h" +#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/trace/span_context.h" #include "opentelemetry/version.h" @@ -16,7 +16,7 @@ namespace sdk { namespace metrics { -using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; +using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; /** * A sample input measurement. * diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h index f3bc904e26..a5fd8966e3 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h @@ -5,7 +5,7 @@ #include -#include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -23,7 +23,7 @@ class OrderedAttributeMap; namespace metrics { -using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; +using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; /** * Exemplar filters are used to pre-filter measurements before attempting to store them in a diff --git a/sdk/include/opentelemetry/sdk/metrics/instruments.h b/sdk/include/opentelemetry/sdk/metrics/instruments.h index 84244128a4..d7c6870945 100644 --- a/sdk/include/opentelemetry/sdk/metrics/instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/instruments.h @@ -6,7 +6,7 @@ #include #include -#include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -63,7 +63,7 @@ struct InstrumentDescriptor InstrumentValueType value_type_; }; -using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; +using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; using AggregationTemporalitySelector = std::function; /*class InstrumentSelector { diff --git a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h index 8dd820fd95..e5d6b75b42 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h @@ -69,6 +69,7 @@ class AttributesHashMap * value and store in the hash */ Aggregation *GetOrSetDefault(const opentelemetry::common::KeyValueIterable &attributes, + const AttributesProcessor *attributes_processor, std::function()> aggregation_callback, size_t hash) { @@ -83,7 +84,7 @@ class AttributesHashMap return GetOrSetOveflowAttributes(aggregation_callback); } - MetricAttributes attr{attributes}; + MetricAttributes attr{attributes, attributes_processor}; hash_map_[hash] = {attr, aggregation_callback()}; return hash_map_[hash].second.get(); @@ -109,6 +110,7 @@ class AttributesHashMap } Aggregation *GetOrSetDefault(const MetricAttributes &attributes, + const AttributesProcessor *attributes_processor, std::function()> aggregation_callback, size_t hash) { @@ -133,6 +135,7 @@ class AttributesHashMap * Set the value for given key, overwriting the value if already present */ void Set(const opentelemetry::common::KeyValueIterable &attributes, + const AttributesProcessor *attributes_processor, std::unique_ptr aggr, size_t hash) { @@ -149,12 +152,15 @@ class AttributesHashMap } else { - MetricAttributes attr{attributes}; + MetricAttributes attr{attributes, attributes_processor}; hash_map_[hash] = {attr, std::move(aggr)}; } } - void Set(const MetricAttributes &attributes, std::unique_ptr aggr, size_t hash) + void Set(const MetricAttributes &attributes, + const AttributesProcessor *attributes_processor, + std::unique_ptr aggr, + size_t hash) { auto it = hash_map_.find(hash); if (it != hash_map_.end()) diff --git a/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h b/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h new file mode 100644 index 0000000000..49a0241821 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include "opentelemetry/sdk/common/attributemap_hash.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class AttributesProcessor; +class FilteredOrderedAttributeMap : public opentelemetry::sdk::common::OrderedAttributeMap +{ +public: + FilteredOrderedAttributeMap() = default; + FilteredOrderedAttributeMap(const FilteredOrderedAttributeMap &other) = default; + FilteredOrderedAttributeMap( + std::initializer_list> + attributes) + : OrderedAttributeMap(attributes) + {} + FilteredOrderedAttributeMap(const opentelemetry::common::KeyValueIterable &attributes) + : FilteredOrderedAttributeMap(attributes, nullptr) + {} + FilteredOrderedAttributeMap(const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::sdk::metrics::AttributesProcessor *processor); + FilteredOrderedAttributeMap( + std::initializer_list> + attributes, + const opentelemetry::sdk::metrics::AttributesProcessor *processor); +}; +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h index cf249c39f2..6168415ff1 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h @@ -99,7 +99,8 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage }); std::lock_guard guard(attribute_hashmap_lock_); - attributes_hashmap_->GetOrSetDefault(attributes, create_default_aggregation_, hash) + attributes_hashmap_ + ->GetOrSetDefault(attributes, attributes_processor_, create_default_aggregation_, hash) ->Aggregate(value); } @@ -148,7 +149,8 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage } }); std::lock_guard guard(attribute_hashmap_lock_); - attributes_hashmap_->GetOrSetDefault(attributes, create_default_aggregation_, hash) + attributes_hashmap_ + ->GetOrSetDefault(attributes, attributes_processor_, create_default_aggregation_, hash) ->Aggregate(value); } diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 91e4b268cf..3653261f33 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -5,11 +5,12 @@ #include #include +#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/common/key_value_iterable.h" #include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/sdk/metrics/instruments.h" +//#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -17,7 +18,7 @@ namespace sdk { namespace metrics { -using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; +using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; /** * The AttributesProcessor is responsible for customizing which diff --git a/sdk/src/metrics/CMakeLists.txt b/sdk/src/metrics/CMakeLists.txt index a0c9aa6771..134b227893 100644 --- a/sdk/src/metrics/CMakeLists.txt +++ b/sdk/src/metrics/CMakeLists.txt @@ -13,6 +13,7 @@ add_library( instrument_metadata_validator.cc export/periodic_exporting_metric_reader.cc export/periodic_exporting_metric_reader_factory.cc + state/filtered_ordered_attribute_map.cc state/metric_collector.cc state/observable_registry.cc state/sync_metric_storage.cc diff --git a/sdk/src/metrics/state/filtered_ordered_attribute_map.cc b/sdk/src/metrics/state/filtered_ordered_attribute_map.cc new file mode 100644 index 0000000000..1af0fe0d92 --- /dev/null +++ b/sdk/src/metrics/state/filtered_ordered_attribute_map.cc @@ -0,0 +1,43 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" +#include "opentelemetry/sdk/metrics/view/attributes_processor.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +FilteredOrderedAttributeMap::FilteredOrderedAttributeMap( + const opentelemetry::common::KeyValueIterable &attributes, + const AttributesProcessor *processor) + : OrderedAttributeMap() +{ + attributes.ForEachKeyValue( + [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { + if (processor && processor->isPresent(key)) + { + SetAttribute(key, value); + } + return true; + }); +} + +FilteredOrderedAttributeMap::FilteredOrderedAttributeMap( + std::initializer_list> + attributes, + const AttributesProcessor *processor) + : OrderedAttributeMap() +{ + for (auto &kv : attributes) + { + if (processor && processor->isPresent(kv.first)) + { + SetAttribute(kv.first, kv.second); + } + } +} +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE From f4d98e21d1511ab4dd18ca1c16e7338f2b40386a Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 2 Jan 2024 20:02:47 +0000 Subject: [PATCH 2/5] fix async --- .../opentelemetry/sdk/metrics/observer_result.h | 10 +--------- .../sdk/metrics/state/attributes_hashmap.h | 5 +---- sdk/test/metrics/cardinality_limit_test.cc | 6 +++--- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/observer_result.h b/sdk/include/opentelemetry/sdk/metrics/observer_result.h index 38c5843633..52e3d9e873 100644 --- a/sdk/include/opentelemetry/sdk/metrics/observer_result.h +++ b/sdk/include/opentelemetry/sdk/metrics/observer_result.h @@ -30,15 +30,7 @@ class ObserverResultT final : public opentelemetry::metrics::ObserverResultT void Observe(T value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override { - if (attributes_processor_) - { - auto attr = attributes_processor_->process(attributes); - data_.insert({attr, value}); - } - else - { - data_.insert({MetricAttributes{attributes}, value}); - } + data_.insert({MetricAttributes{attributes, attributes_processor_}, value}); } const std::unordered_map &GetMeasurements() diff --git a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h index e5d6b75b42..bed4b050b3 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h @@ -110,7 +110,6 @@ class AttributesHashMap } Aggregation *GetOrSetDefault(const MetricAttributes &attributes, - const AttributesProcessor *attributes_processor, std::function()> aggregation_callback, size_t hash) { @@ -158,7 +157,6 @@ class AttributesHashMap } void Set(const MetricAttributes &attributes, - const AttributesProcessor *attributes_processor, std::unique_ptr aggr, size_t hash) { @@ -175,8 +173,7 @@ class AttributesHashMap } else { - MetricAttributes attr{attributes}; - hash_map_[hash] = {attr, std::move(aggr)}; + hash_map_[hash] = {attributes, std::move(aggr)}; } } diff --git a/sdk/test/metrics/cardinality_limit_test.cc b/sdk/test/metrics/cardinality_limit_test.cc index d290f889b5..20dfcb3178 100644 --- a/sdk/test/metrics/cardinality_limit_test.cc +++ b/sdk/test/metrics/cardinality_limit_test.cc @@ -26,7 +26,7 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) long record_value = 100; for (auto i = 0; i < 10; i++) { - OrderedAttributeMap attributes = {{"key", std::to_string(i)}}; + FilteredOrderedAttributeMap attributes = {{"key", std::to_string(i)}}; auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); static_cast( hash_map.GetOrSetDefault(attributes, aggregation_callback, hash)) @@ -37,7 +37,7 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) // overflowmetric point. for (auto i = 10; i < 15; i++) { - OrderedAttributeMap attributes = {{"key", std::to_string(i)}}; + FilteredOrderedAttributeMap attributes = {{"key", std::to_string(i)}}; auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); static_cast( hash_map.GetOrSetDefault(attributes, aggregation_callback, hash)) @@ -46,7 +46,7 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) EXPECT_EQ(hash_map.Size(), 10); // only one more metric point should be added as overflow. // get the overflow metric point auto agg = hash_map.GetOrSetDefault( - OrderedAttributeMap({{kAttributesLimitOverflowKey, kAttributesLimitOverflowValue}}), + FilteredOrderedAttributeMap({{kAttributesLimitOverflowKey, kAttributesLimitOverflowValue}}), aggregation_callback, kOverflowAttributesHash); EXPECT_NE(agg, nullptr); auto sum_agg = static_cast(agg); From 1a2881adef50033b48e4880782914fddf57a6e77 Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 2 Jan 2024 12:06:25 -0800 Subject: [PATCH 3/5] format --- sdk/include/opentelemetry/sdk/metrics/observer_result.h | 2 +- .../opentelemetry/sdk/metrics/state/attributes_hashmap.h | 4 +--- sdk/test/metrics/cardinality_limit_test.cc | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/observer_result.h b/sdk/include/opentelemetry/sdk/metrics/observer_result.h index 52e3d9e873..5be40329c1 100644 --- a/sdk/include/opentelemetry/sdk/metrics/observer_result.h +++ b/sdk/include/opentelemetry/sdk/metrics/observer_result.h @@ -30,7 +30,7 @@ class ObserverResultT final : public opentelemetry::metrics::ObserverResultT void Observe(T value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override { - data_.insert({MetricAttributes{attributes, attributes_processor_}, value}); + data_.insert({MetricAttributes{attributes, attributes_processor_}, value}); } const std::unordered_map &GetMeasurements() diff --git a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h index bed4b050b3..adc3f415af 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h @@ -156,9 +156,7 @@ class AttributesHashMap } } - void Set(const MetricAttributes &attributes, - std::unique_ptr aggr, - size_t hash) + void Set(const MetricAttributes &attributes, std::unique_ptr aggr, size_t hash) { auto it = hash_map_.find(hash); if (it != hash_map_.end()) diff --git a/sdk/test/metrics/cardinality_limit_test.cc b/sdk/test/metrics/cardinality_limit_test.cc index 20dfcb3178..621241557b 100644 --- a/sdk/test/metrics/cardinality_limit_test.cc +++ b/sdk/test/metrics/cardinality_limit_test.cc @@ -27,7 +27,7 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) for (auto i = 0; i < 10; i++) { FilteredOrderedAttributeMap attributes = {{"key", std::to_string(i)}}; - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); + auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); static_cast( hash_map.GetOrSetDefault(attributes, aggregation_callback, hash)) ->Aggregate(record_value); @@ -38,7 +38,7 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) for (auto i = 10; i < 15; i++) { FilteredOrderedAttributeMap attributes = {{"key", std::to_string(i)}}; - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); + auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); static_cast( hash_map.GetOrSetDefault(attributes, aggregation_callback, hash)) ->Aggregate(record_value); From b2174a1eb927677f243b5441ea9d25266e5ff3cd Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 2 Jan 2024 13:26:05 -0800 Subject: [PATCH 4/5] handle deprecated copy warning --- .../sdk/metrics/state/filtered_ordered_attribute_map.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h b/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h index 49a0241821..f9880b5073 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h @@ -17,8 +17,7 @@ class AttributesProcessor; class FilteredOrderedAttributeMap : public opentelemetry::sdk::common::OrderedAttributeMap { public: - FilteredOrderedAttributeMap() = default; - FilteredOrderedAttributeMap(const FilteredOrderedAttributeMap &other) = default; + FilteredOrderedAttributeMap() = default; FilteredOrderedAttributeMap( std::initializer_list> attributes) From c7a9687b1b590f69a343ebe174cadd9db5286005 Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 2 Jan 2024 23:55:43 -0800 Subject: [PATCH 5/5] format --- .../sdk/metrics/view/attributes_processor.h | 4 +- sdk/test/metrics/sum_aggregation_test.cc | 108 ++++++++++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 3653261f33..a71abb7a99 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -5,12 +5,10 @@ #include #include -#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" - #include "opentelemetry/common/key_value_iterable.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/sdk/metrics/instruments.h" -//#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" +#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE diff --git a/sdk/test/metrics/sum_aggregation_test.cc b/sdk/test/metrics/sum_aggregation_test.cc index 403bf34b22..33a111974e 100644 --- a/sdk/test/metrics/sum_aggregation_test.cc +++ b/sdk/test/metrics/sum_aggregation_test.cc @@ -72,6 +72,60 @@ TEST(HistogramToSum, Double) ASSERT_EQ(1000275.0, opentelemetry::nostd::get(actual.value_)); } +TEST(HistogramToSumFilterAttributes, Double) +{ + MeterProvider mp; + auto m = mp.GetMeter("meter1", "version1", "schema1"); + std::string instrument_unit = "ms"; + std::string instrument_name = "historgram1"; + std::string instrument_desc = "histogram metrics"; + + std::unordered_map allowedattr; + allowedattr["attr1"] = true; + std::unique_ptr attrproc{ + new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; + + std::shared_ptr dummy_aggregation_config{ + new opentelemetry::sdk::metrics::AggregationConfig}; + std::unique_ptr exporter(new MockMetricExporter()); + std::shared_ptr reader{new MockMetricReader(std::move(exporter))}; + mp.AddMetricReader(reader); + + std::unique_ptr view{new View("view1", "view1_description", instrument_unit, + AggregationType::kSum, dummy_aggregation_config, + std::move(attrproc))}; + std::unique_ptr instrument_selector{ + new InstrumentSelector(InstrumentType::kHistogram, instrument_name, instrument_unit)}; + std::unique_ptr meter_selector{new MeterSelector("meter1", "version1", "schema1")}; + mp.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view)); + + auto h = m->CreateDoubleHistogram(instrument_name, instrument_desc, instrument_unit); + std::unordered_map attr1 = {{"attr1", "val1"}, {"attr2", "val2"}}; + std::unordered_map attr2 = {{"attr1", "val1"}, {"attr2", "val2"}}; + h->Record(5, attr1, opentelemetry::context::Context{}); + h->Record(10, attr2, opentelemetry::context::Context{}); + + reader->Collect([&](ResourceMetrics &rm) { + for (const ScopeMetrics &smd : rm.scope_metric_data_) + { + for (const MetricData &md : smd.metric_data_) + { + EXPECT_EQ(1, md.point_data_attr_.size()); + if (md.point_data_attr_.size() == 1) + { + EXPECT_EQ(15.0, opentelemetry::nostd::get(opentelemetry::nostd::get( + md.point_data_attr_[0].point_data) + .value_)); + EXPECT_EQ(1, md.point_data_attr_[0].attributes.size()); + EXPECT_NE(md.point_data_attr_[0].attributes.end(), + md.point_data_attr_[0].attributes.find("attr1")); + } + } + } + return true; + }); +} + TEST(CounterToSum, Double) { MeterProvider mp; @@ -121,6 +175,60 @@ TEST(CounterToSum, Double) ASSERT_EQ(1000275.0, opentelemetry::nostd::get(actual.value_)); } +TEST(CounterToSumFilterAttributes, Double) +{ + MeterProvider mp; + auto m = mp.GetMeter("meter1", "version1", "schema1"); + std::string instrument_unit = "ms"; + std::string instrument_name = "counter1"; + std::string instrument_desc = "counter metrics"; + + std::unordered_map allowedattr; + allowedattr["attr1"] = true; + std::unique_ptr attrproc{ + new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; + + std::shared_ptr dummy_aggregation_config{ + new opentelemetry::sdk::metrics::AggregationConfig}; + std::unique_ptr exporter(new MockMetricExporter()); + std::shared_ptr reader{new MockMetricReader(std::move(exporter))}; + mp.AddMetricReader(reader); + + std::unique_ptr view{new View("view1", "view1_description", instrument_unit, + AggregationType::kSum, dummy_aggregation_config, + std::move(attrproc))}; + std::unique_ptr instrument_selector{ + new InstrumentSelector(InstrumentType::kCounter, instrument_name, instrument_unit)}; + std::unique_ptr meter_selector{new MeterSelector("meter1", "version1", "schema1")}; + mp.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view)); + + auto c = m->CreateDoubleCounter(instrument_name, instrument_desc, instrument_unit); + std::unordered_map attr1 = {{"attr1", "val1"}, {"attr2", "val2"}}; + std::unordered_map attr2 = {{"attr1", "val1"}, {"attr2", "val2"}}; + c->Add(5, attr1, opentelemetry::context::Context{}); + c->Add(10, attr2, opentelemetry::context::Context{}); + + reader->Collect([&](ResourceMetrics &rm) { + for (const ScopeMetrics &smd : rm.scope_metric_data_) + { + for (const MetricData &md : smd.metric_data_) + { + EXPECT_EQ(1, md.point_data_attr_.size()); + if (md.point_data_attr_.size() == 1) + { + EXPECT_EQ(15.0, opentelemetry::nostd::get(opentelemetry::nostd::get( + md.point_data_attr_[0].point_data) + .value_)); + EXPECT_EQ(1, md.point_data_attr_[0].attributes.size()); + EXPECT_NE(md.point_data_attr_[0].attributes.end(), + md.point_data_attr_[0].attributes.find("attr1")); + } + } + } + return true; + }); +} + class UpDownCounterToSumFixture : public ::testing::TestWithParam {};