| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- // Copyright The OpenTelemetry Authors
- // SPDX-License-Identifier: Apache-2.0
- #include <gtest/gtest.h>
- #include <stdint.h>
- #include <algorithm>
- #include <map>
- #include <memory>
- #include <string>
- #include <utility>
- #include <vector>
- #include "common.h"
- #include "gmock/gmock.h"
- #include "opentelemetry/common/key_value_iterable_view.h"
- #include "opentelemetry/context/context.h"
- #include "opentelemetry/metrics/sync_instruments.h" // IWYU pragma: keep
- #include "opentelemetry/nostd/string_view.h"
- #include "opentelemetry/nostd/variant.h"
- #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
- #include "opentelemetry/sdk/metrics/data/metric_data.h"
- #include "opentelemetry/sdk/metrics/data/point_data.h"
- #include "opentelemetry/sdk/metrics/export/metric_filter.h"
- #include "opentelemetry/sdk/metrics/export/metric_producer.h"
- #include "opentelemetry/sdk/metrics/instruments.h"
- #include "opentelemetry/sdk/metrics/meter.h"
- #include "opentelemetry/sdk/metrics/meter_context.h"
- #include "opentelemetry/sdk/metrics/metric_reader.h"
- #include "opentelemetry/sdk/metrics/state/metric_collector.h"
- #include "opentelemetry/sdk/metrics/view/view_registry.h"
- #include "opentelemetry/sdk/metrics/view/view_registry_factory.h"
- #if defined(__GNUC__) || defined(__clang__) || defined(__apple_build_version__)
- # pragma GCC diagnostic push
- # pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- using namespace opentelemetry;
- using namespace opentelemetry::sdk::instrumentationscope;
- using namespace opentelemetry::sdk::metrics;
- using namespace testing;
- using M = std::map<std::string, std::string>;
- namespace
- {
- MetricFilter::TestMetricFn AcceptAllTestMetricFn()
- {
- return [](const InstrumentationScope &scope, nostd::string_view name, const InstrumentType &type,
- nostd::string_view unit) -> MetricFilter::MetricFilterResult {
- return MetricFilter::MetricFilterResult::kAccept;
- };
- }
- MetricFilter::TestMetricFn DropAllTestMetricFn()
- {
- return [](const InstrumentationScope &scope, nostd::string_view name, const InstrumentType &type,
- nostd::string_view unit) -> MetricFilter::MetricFilterResult {
- return MetricFilter::MetricFilterResult::kDrop;
- };
- }
- MetricFilter::TestMetricFn AcceptPartialAllTestMetricFn()
- {
- return [](const InstrumentationScope &scope, nostd::string_view name, const InstrumentType &type,
- nostd::string_view unit) -> MetricFilter::MetricFilterResult {
- return MetricFilter::MetricFilterResult::kAcceptPartial;
- };
- }
- MetricFilter::TestAttributesFn AcceptAllTestAttributesFn()
- {
- return [](const InstrumentationScope &scope, nostd::string_view name, const InstrumentType &type,
- nostd::string_view unit,
- const PointAttributes &attributes) -> MetricFilter::AttributesFilterResult {
- return MetricFilter::AttributesFilterResult::kAccept;
- };
- }
- MetricFilter::TestAttributesFn DropAllTestAttributesFn()
- {
- return [](const InstrumentationScope &scope, nostd::string_view name, const InstrumentType &type,
- nostd::string_view unit,
- const PointAttributes &attributes) -> MetricFilter::AttributesFilterResult {
- return MetricFilter::AttributesFilterResult::kDrop;
- };
- }
- } // namespace
- class testing::MetricCollectorTest : public Test
- {
- public:
- std::weak_ptr<MetricCollector> AddMetricReaderToMeterContext(
- std::shared_ptr<MeterContext> context,
- std::shared_ptr<MetricReader> reader,
- std::unique_ptr<MetricFilter> metric_filter = nullptr) noexcept
- {
- auto collector = std::shared_ptr<MetricCollector>{
- new MetricCollector(context.get(), std::move(reader), std::move(metric_filter))};
- context->collectors_.push_back(collector);
- return std::weak_ptr<MetricCollector>(collector);
- }
- };
- TEST_F(MetricCollectorTest, CollectWithMetricFilterTestMetricTest1)
- {
- auto context = std::shared_ptr<MeterContext>(new MeterContext(ViewRegistryFactory::Create()));
- auto scope = InstrumentationScope::Create("CollectWithMetricFilterTestMetricTest1");
- auto meter = std::shared_ptr<Meter>(new Meter(context, std::move(scope)));
- context->AddMeter(meter);
- auto filter = MetricFilter::Create(AcceptAllTestMetricFn(), DropAllTestAttributesFn());
- auto reader = std::shared_ptr<MetricReader>(new MockMetricReader());
- auto collector = AddMetricReaderToMeterContext(context, reader, std::move(filter)).lock();
- auto instrument_1_name = "instrument_1";
- auto instrument_1 = meter->CreateUInt64Counter(instrument_1_name);
- auto instrument_2_name = "instrument_2";
- auto instrument_2 = meter->CreateUInt64Counter(instrument_2_name);
- M m_2 = {{"stream", "1"}};
- instrument_2->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_2),
- opentelemetry::context::Context{});
- auto instrument_3_name = "instrument_3";
- auto instrument_3 = meter->CreateUInt64Counter(instrument_3_name);
- for (int s = 1; s <= 10; ++s)
- {
- for (int i = 0; i < s; ++i)
- {
- M m_3 = {{"stream", std::to_string(s)}};
- instrument_3->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_3),
- opentelemetry::context::Context{});
- }
- }
- auto resource_metrics = collector->Produce().points_;
- for (const ScopeMetrics &scope_metrics : resource_metrics.scope_metric_data_)
- {
- for (const MetricData &metric : scope_metrics.metric_data_)
- {
- auto instrument_name = metric.instrument_descriptor.name_;
- ASSERT_TRUE(instrument_name == instrument_2_name || instrument_name == instrument_3_name);
- if (instrument_name == instrument_2_name)
- {
- EXPECT_EQ(metric.point_data_attr_.size(), 1);
- }
- else if (instrument_name == instrument_3_name)
- {
- EXPECT_EQ(metric.point_data_attr_.size(), 10);
- }
- }
- }
- }
- TEST_F(MetricCollectorTest, CollectWithMetricFilterTestMetricTest2)
- {
- auto context = std::shared_ptr<MeterContext>(new MeterContext(ViewRegistryFactory::Create()));
- auto scope = InstrumentationScope::Create("CollectWithMetricFilterTestMetricTest2");
- auto meter = std::shared_ptr<Meter>(new Meter(context, std::move(scope)));
- context->AddMeter(meter);
- auto filter = MetricFilter::Create(DropAllTestMetricFn(), AcceptAllTestAttributesFn());
- auto reader = std::shared_ptr<MetricReader>(new MockMetricReader());
- auto collector = AddMetricReaderToMeterContext(context, reader, std::move(filter)).lock();
- auto instrument_1_name = "instrument_1";
- auto instrument_1 = meter->CreateUInt64Counter(instrument_1_name);
- auto instrument_2_name = "instrument_2";
- auto instrument_2 = meter->CreateUInt64Counter(instrument_2_name);
- M m_2 = {{"stream", "1"}};
- instrument_2->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_2),
- opentelemetry::context::Context{});
- auto instrument_3_name = "instrument_3";
- auto instrument_3 = meter->CreateUInt64Counter(instrument_3_name);
- for (int s = 1; s <= 10; ++s)
- {
- for (int i = 0; i < s; ++i)
- {
- M m_3 = {{"stream", std::to_string(s)}};
- instrument_3->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_3),
- opentelemetry::context::Context{});
- }
- }
- auto resource_metrics = collector->Produce().points_;
- EXPECT_EQ(resource_metrics.scope_metric_data_.size(), 0);
- }
- TEST_F(MetricCollectorTest, CollectWithMetricFilterTestMetricTest3)
- {
- auto context = std::shared_ptr<MeterContext>(new MeterContext(ViewRegistryFactory::Create()));
- auto scope = InstrumentationScope::Create("CollectWithMetricFilterTestMetricTest3");
- auto meter = std::shared_ptr<Meter>(new Meter(context, std::move(scope)));
- context->AddMeter(meter);
- auto test_metric_fn = [](const InstrumentationScope &scope, nostd::string_view name,
- const InstrumentType &type,
- nostd::string_view unit) -> MetricFilter::MetricFilterResult {
- std::string name_copy = {name.begin(), name.end()};
- if (name_copy.find("_accept") != std::string::npos)
- {
- return MetricFilter::MetricFilterResult::kAccept;
- }
- return MetricFilter::MetricFilterResult::kDrop;
- };
- auto filter = MetricFilter::Create(test_metric_fn, DropAllTestAttributesFn());
- auto reader = std::shared_ptr<MetricReader>(new MockMetricReader());
- auto collector = AddMetricReaderToMeterContext(context, reader, std::move(filter)).lock();
- auto instrument_1_name = "instrument_1";
- auto instrument_1 = meter->CreateUInt64Counter(instrument_1_name);
- auto instrument_2_name = "instrument_2";
- auto instrument_2 = meter->CreateUInt64Counter(instrument_2_name);
- M m_2 = {{"stream", "1"}};
- instrument_2->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_2),
- opentelemetry::context::Context{});
- auto instrument_3_name = "instrument_3_accept";
- auto instrument_3 = meter->CreateUInt64Counter(instrument_3_name);
- for (int s = 1; s <= 10; ++s)
- {
- for (int i = 0; i < s; ++i)
- {
- M m_3 = {{"stream", std::to_string(s)}};
- instrument_3->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_3),
- opentelemetry::context::Context{});
- }
- }
- auto resource_metrics = collector->Produce().points_;
- for (const ScopeMetrics &scope_metrics : resource_metrics.scope_metric_data_)
- {
- for (const MetricData &metric : scope_metrics.metric_data_)
- {
- auto instrument_name = metric.instrument_descriptor.name_;
- ASSERT_EQ(instrument_name, instrument_3_name);
- EXPECT_EQ(metric.point_data_attr_.size(), 10);
- }
- }
- }
- TEST_F(MetricCollectorTest, CollectWithMetricFilterTestAttributesTest1)
- {
- auto context = std::shared_ptr<MeterContext>(new MeterContext(ViewRegistryFactory::Create()));
- auto scope = InstrumentationScope::Create("CollectWithMetricFilterTestAttributesTest1");
- auto meter = std::shared_ptr<Meter>(new Meter(context, std::move(scope)));
- context->AddMeter(meter);
- auto test_attributes_fn =
- [](const InstrumentationScope &scope, nostd::string_view name, const InstrumentType &type,
- nostd::string_view unit,
- const PointAttributes &attributes) -> MetricFilter::AttributesFilterResult {
- if (attributes.GetAttributes().find("stream") != attributes.GetAttributes().end())
- {
- return MetricFilter::AttributesFilterResult::kAccept;
- }
- return MetricFilter::AttributesFilterResult::kDrop;
- };
- auto filter = MetricFilter::Create(AcceptPartialAllTestMetricFn(), test_attributes_fn);
- auto reader = std::shared_ptr<MetricReader>(new MockMetricReader());
- auto collector = AddMetricReaderToMeterContext(context, reader, std::move(filter)).lock();
- auto instrument_1_name = "instrument_1";
- auto instrument_1 = meter->CreateUInt64Counter(instrument_1_name);
- M m_1 = {{"ocean", "1"}};
- instrument_1->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_1),
- opentelemetry::context::Context{});
- auto instrument_2_name = "instrument_2";
- auto instrument_2 = meter->CreateUInt64Counter(instrument_2_name);
- M m_2 = {{"stream", "1"}, {"river", "10"}};
- instrument_2->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_2),
- opentelemetry::context::Context{});
- auto instrument_3_name = "instrument_3";
- auto instrument_3 = meter->CreateUInt64Counter(instrument_3_name);
- for (int s = 1; s <= 10; ++s)
- {
- for (int i = 0; i < s; ++i)
- {
- M m_3 = {{"stream", std::to_string(s)}, {"river", std::to_string(s * 10)}};
- instrument_3->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_3),
- opentelemetry::context::Context{});
- }
- }
- auto resource_metrics = collector->Produce().points_;
- for (const ScopeMetrics &scope_metrics : resource_metrics.scope_metric_data_)
- {
- for (const MetricData &metric : scope_metrics.metric_data_)
- {
- auto instrument_name = metric.instrument_descriptor.name_;
- ASSERT_TRUE(instrument_name == instrument_2_name || instrument_name == instrument_3_name);
- if (instrument_name == instrument_2_name)
- {
- EXPECT_EQ(metric.point_data_attr_.size(), 1);
- }
- else if (instrument_name == instrument_3_name)
- {
- EXPECT_EQ(metric.point_data_attr_.size(), 10);
- for (const PointDataAttributes &pda : metric.point_data_attr_)
- {
- auto sum_point_data = nostd::get<SumPointData>(pda.point_data);
- auto value = nostd::get<int64_t>(sum_point_data.value_);
- auto stream =
- std::stoi(nostd::get<std::string>(pda.attributes.GetAttributes().at("stream")));
- auto river =
- std::stoi(nostd::get<std::string>(pda.attributes.GetAttributes().at("river")));
- std::vector<int64_t> stream_v = {value, stream};
- std::vector<int64_t> river_v = {value, river};
- EXPECT_THAT(stream_v, AnyOf(ElementsAre(1, 1), ElementsAre(2, 2), ElementsAre(3, 3),
- ElementsAre(4, 4), ElementsAre(5, 5), ElementsAre(6, 6),
- ElementsAre(7, 7), ElementsAre(8, 8), ElementsAre(9, 9),
- ElementsAre(10, 10)));
- EXPECT_THAT(river_v, AnyOf(ElementsAre(1, 10), ElementsAre(2, 20), ElementsAre(3, 30),
- ElementsAre(4, 40), ElementsAre(5, 50), ElementsAre(6, 60),
- ElementsAre(7, 70), ElementsAre(8, 80), ElementsAre(9, 90),
- ElementsAre(10, 100)));
- }
- }
- }
- }
- }
- TEST_F(MetricCollectorTest, CollectWithMetricFilterTestAttributesTest2)
- {
- auto context = std::shared_ptr<MeterContext>(new MeterContext(ViewRegistryFactory::Create()));
- auto scope = InstrumentationScope::Create("CollectWithMetricFilterTestAttributesTest2");
- auto meter = std::shared_ptr<Meter>(new Meter(context, std::move(scope)));
- context->AddMeter(meter);
- auto test_attributes_fn =
- [](const InstrumentationScope &scope, nostd::string_view name, const InstrumentType &type,
- nostd::string_view unit,
- const PointAttributes &attributes) -> MetricFilter::AttributesFilterResult {
- if (attributes.GetAttributes().find("stream") != attributes.GetAttributes().end())
- {
- auto stream = nostd::get<std::string>(attributes.GetAttributes().at("stream"));
- if (std::stoi(stream) >= 4 && std::stoi(stream) <= 6)
- {
- return MetricFilter::AttributesFilterResult::kAccept;
- }
- }
- return MetricFilter::AttributesFilterResult::kDrop;
- };
- auto filter = MetricFilter::Create(AcceptPartialAllTestMetricFn(), test_attributes_fn);
- auto reader = std::shared_ptr<MetricReader>(new MockMetricReader());
- auto collector = AddMetricReaderToMeterContext(context, reader, std::move(filter)).lock();
- auto instrument_1_name = "instrument_1";
- auto instrument_1 = meter->CreateUInt64Counter(instrument_1_name);
- M m_1 = {{"ocean", "1"}};
- instrument_1->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_1),
- opentelemetry::context::Context{});
- auto instrument_2_name = "instrument_2";
- auto instrument_2 = meter->CreateUInt64Counter(instrument_2_name);
- M m_2 = {{"stream", "1"}, {"river", "10"}};
- instrument_2->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_2),
- opentelemetry::context::Context{});
- auto instrument_3_name = "instrument_3";
- auto instrument_3 = meter->CreateUInt64Counter(instrument_3_name);
- for (int s = 1; s <= 10; ++s)
- {
- for (int i = 0; i < s; ++i)
- {
- M m_3 = {{"stream", std::to_string(s)}, {"river", std::to_string(s * 10)}};
- instrument_3->Add(1, opentelemetry::common::KeyValueIterableView<M>(m_3),
- opentelemetry::context::Context{});
- }
- }
- auto resource_metrics = collector->Produce().points_;
- for (const ScopeMetrics &scope_metrics : resource_metrics.scope_metric_data_)
- {
- for (const MetricData &metric : scope_metrics.metric_data_)
- {
- auto instrument_name = metric.instrument_descriptor.name_;
- ASSERT_EQ(instrument_name, instrument_3_name);
- EXPECT_EQ(metric.point_data_attr_.size(), 3);
- for (const PointDataAttributes &pda : metric.point_data_attr_)
- {
- auto sum_point_data = nostd::get<SumPointData>(pda.point_data);
- auto value = nostd::get<int64_t>(sum_point_data.value_);
- auto stream =
- std::stoi(nostd::get<std::string>(pda.attributes.GetAttributes().at("stream")));
- auto river = std::stoi(nostd::get<std::string>(pda.attributes.GetAttributes().at("river")));
- std::vector<int64_t> stream_v = {value, stream};
- std::vector<int64_t> river_v = {value, river};
- EXPECT_THAT(stream_v, AnyOf(ElementsAre(4, 4), ElementsAre(5, 5), ElementsAre(6, 6)));
- EXPECT_THAT(river_v, AnyOf(ElementsAre(4, 40), ElementsAre(5, 50), ElementsAre(6, 60)));
- }
- }
- }
- }
- #if defined(__GNUC__) || defined(__clang__) || defined(__apple_build_version__)
- # pragma GCC diagnostic pop
- #endif
|