| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- // Copyright The OpenTelemetry Authors
- // SPDX-License-Identifier: Apache-2.0
- #include <gtest/gtest.h>
- #include <algorithm>
- #include <chrono>
- #include <cstdint>
- #include <map>
- #include <memory>
- #include <string>
- #include <unordered_map>
- #include <utility>
- #include <vector>
- #include "common.h"
- #include "opentelemetry/common/timestamp.h"
- #include "opentelemetry/nostd/function_ref.h"
- #include "opentelemetry/nostd/span.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_producer.h"
- #include "opentelemetry/sdk/metrics/instruments.h"
- #include "opentelemetry/sdk/metrics/state/async_metric_storage.h"
- #include "opentelemetry/sdk/metrics/state/attributes_hashmap.h"
- #include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h"
- #include "opentelemetry/sdk/metrics/state/metric_collector.h"
- #include "opentelemetry/sdk/metrics/view/attributes_processor.h"
- #ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW
- # include "opentelemetry/sdk/metrics/exemplar/filter_type.h"
- # include "opentelemetry/sdk/metrics/exemplar/reservoir.h"
- #endif
- using namespace opentelemetry::sdk::metrics;
- using namespace opentelemetry::sdk::instrumentationscope;
- using namespace opentelemetry::sdk::resource;
- using namespace opentelemetry::common;
- namespace nostd = opentelemetry::nostd;
- using M = std::map<std::string, std::string>;
- class WritableMetricStorageTestFixture : public ::testing::TestWithParam<AggregationTemporality>
- {};
- class WritableMetricStorageTestUpDownFixture
- : public ::testing::TestWithParam<AggregationTemporality>
- {};
- class WritableMetricStorageTestObservableGaugeFixture
- : public ::testing::TestWithParam<AggregationTemporality>
- {};
- TEST_P(WritableMetricStorageTestFixture, TestAggregation)
- {
- AggregationTemporality temporality = GetParam();
- InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kObservableCounter,
- InstrumentValueType::kLong};
- auto sdk_start_ts = std::chrono::system_clock::now();
- // Some computation here
- auto collection_ts = std::chrono::system_clock::now() + std::chrono::seconds(5);
- std::shared_ptr<CollectorHandle> collector(new MockCollectorHandle(temporality));
- std::vector<std::shared_ptr<CollectorHandle>> collectors;
- collectors.push_back(collector);
- opentelemetry::sdk::metrics::AsyncMetricStorage storage(
- instr_desc, AggregationType::kSum,
- #ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW
- ExemplarFilterType::kAlwaysOff, ExemplarReservoir::GetNoExemplarReservoir(),
- #endif
- nullptr);
- int64_t get_count1 = 20;
- int64_t put_count1 = 10;
- std::unordered_map<MetricAttributes, int64_t, AttributeHashGenerator> measurements1 = {
- {{{"RequestType", "GET"}}, get_count1}, {{{"RequestType", "PUT"}}, put_count1}};
- storage.RecordLong(measurements1,
- opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()));
- storage.Collect(
- collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) {
- for (const auto &data_attr : metric_data.point_data_attr_)
- {
- const auto &data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data);
- if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("RequestType")->second) == "GET")
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), get_count1);
- }
- else if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("RequestType")->second) == "PUT")
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), put_count1);
- }
- }
- return true;
- });
- // subsequent recording after collection shouldn't fail
- // monotonic increasing values;
- int64_t get_count2 = 50;
- int64_t put_count2 = 70;
- std::unordered_map<MetricAttributes, int64_t, AttributeHashGenerator> measurements2 = {
- {{{"RequestType", "GET"}}, get_count2}, {{{"RequestType", "PUT"}}, put_count2}};
- storage.RecordLong(measurements2,
- opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()));
- storage.Collect(
- collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) {
- for (const auto &data_attr : metric_data.point_data_attr_)
- {
- const auto &data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data);
- if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("RequestType")->second) == "GET")
- {
- if (temporality == AggregationTemporality::kCumulative)
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), get_count2);
- }
- else
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), get_count2 - get_count1);
- }
- }
- else if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("RequestType")->second) == "PUT")
- {
- if (temporality == AggregationTemporality::kCumulative)
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), put_count2);
- }
- else
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), put_count2 - put_count1);
- }
- }
- }
- return true;
- });
- }
- INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong,
- WritableMetricStorageTestFixture,
- ::testing::Values(AggregationTemporality::kCumulative,
- AggregationTemporality::kDelta));
- TEST_P(WritableMetricStorageTestUpDownFixture, TestAggregation)
- {
- AggregationTemporality temporality = GetParam();
- InstrumentDescriptor instr_desc = {"name", "desc", "1unit",
- InstrumentType::kObservableUpDownCounter,
- InstrumentValueType::kLong};
- auto sdk_start_ts = std::chrono::system_clock::now();
- // Some computation here
- auto collection_ts = std::chrono::system_clock::now() + std::chrono::seconds(5);
- std::shared_ptr<CollectorHandle> collector(new MockCollectorHandle(temporality));
- std::vector<std::shared_ptr<CollectorHandle>> collectors;
- collectors.push_back(collector);
- opentelemetry::sdk::metrics::AsyncMetricStorage storage(
- instr_desc, AggregationType::kDefault,
- #ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW
- ExemplarFilterType::kAlwaysOff, ExemplarReservoir::GetNoExemplarReservoir(),
- #endif
- nullptr);
- int64_t get_count1 = 20;
- int64_t put_count1 = 10;
- std::unordered_map<MetricAttributes, int64_t, AttributeHashGenerator> measurements1 = {
- {{{"RequestType", "GET"}}, get_count1}, {{{"RequestType", "PUT"}}, put_count1}};
- storage.RecordLong(measurements1,
- opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()));
- storage.Collect(
- collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) {
- for (const auto &data_attr : metric_data.point_data_attr_)
- {
- const auto &data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data);
- if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("RequestType")->second) == "GET")
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), get_count1);
- }
- else if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("RequestType")->second) == "PUT")
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), put_count1);
- }
- }
- return true;
- });
- // subsequent recording after collection shouldn't fail
- // monotonic increasing values;
- int64_t get_count2 = -50;
- int64_t put_count2 = -70;
- std::unordered_map<MetricAttributes, int64_t, AttributeHashGenerator> measurements2 = {
- {{{"RequestType", "GET"}}, get_count2}, {{{"RequestType", "PUT"}}, put_count2}};
- storage.RecordLong(measurements2,
- opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()));
- storage.Collect(
- collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) {
- for (const auto &data_attr : metric_data.point_data_attr_)
- {
- const auto &data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data);
- if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("RequestType")->second) == "GET")
- {
- if (temporality == AggregationTemporality::kCumulative)
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), get_count2);
- }
- else
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), get_count2 - get_count1);
- }
- }
- else if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("RequestType")->second) == "PUT")
- {
- if (temporality == AggregationTemporality::kCumulative)
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), put_count2);
- }
- else
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), put_count2 - put_count1);
- }
- }
- }
- return true;
- });
- }
- INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestUpDownLong,
- WritableMetricStorageTestUpDownFixture,
- ::testing::Values(AggregationTemporality::kCumulative,
- AggregationTemporality::kDelta));
- TEST_P(WritableMetricStorageTestObservableGaugeFixture, TestAggregation)
- {
- AggregationTemporality temporality = GetParam();
- InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kObservableGauge,
- InstrumentValueType::kLong};
- auto sdk_start_ts = std::chrono::system_clock::now();
- // Some computation here
- auto collection_ts = std::chrono::system_clock::now() + std::chrono::seconds(5);
- std::shared_ptr<CollectorHandle> collector(new MockCollectorHandle(temporality));
- std::vector<std::shared_ptr<CollectorHandle>> collectors;
- collectors.push_back(collector);
- opentelemetry::sdk::metrics::AsyncMetricStorage storage(
- instr_desc, AggregationType::kLastValue,
- #ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW
- ExemplarFilterType::kAlwaysOff, ExemplarReservoir::GetNoExemplarReservoir(),
- #endif
- nullptr);
- int64_t freq_cpu0 = 3;
- int64_t freq_cpu1 = 5;
- std::unordered_map<MetricAttributes, int64_t, AttributeHashGenerator> measurements1 = {
- {{{"CPU", "0"}}, freq_cpu0}, {{{"CPU", "1"}}, freq_cpu1}};
- storage.RecordLong(measurements1,
- opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()));
- storage.Collect(
- collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) {
- for (auto data_attr : metric_data.point_data_attr_)
- {
- auto data = opentelemetry::nostd::get<LastValuePointData>(data_attr.point_data);
- if (opentelemetry::nostd::get<std::string>(data_attr.attributes.find("CPU")->second) ==
- "0")
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), freq_cpu0);
- }
- else if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("CPU")->second) == "1")
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), freq_cpu1);
- }
- }
- return true;
- });
- freq_cpu0 = 6;
- freq_cpu1 = 8;
- std::unordered_map<MetricAttributes, int64_t, AttributeHashGenerator> measurements2 = {
- {{{"CPU", "0"}}, freq_cpu0}, {{{"CPU", "1"}}, freq_cpu1}};
- storage.RecordLong(measurements2,
- opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()));
- storage.Collect(
- collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) {
- for (auto data_attr : metric_data.point_data_attr_)
- {
- auto data = opentelemetry::nostd::get<LastValuePointData>(data_attr.point_data);
- if (opentelemetry::nostd::get<std::string>(data_attr.attributes.find("CPU")->second) ==
- "0")
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), freq_cpu0);
- }
- else if (opentelemetry::nostd::get<std::string>(
- data_attr.attributes.find("CPU")->second) == "1")
- {
- EXPECT_EQ(opentelemetry::nostd::get<int64_t>(data.value_), freq_cpu1);
- }
- }
- return true;
- });
- }
- INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestObservableGaugeFixtureLong,
- WritableMetricStorageTestObservableGaugeFixture,
- ::testing::Values(AggregationTemporality::kCumulative,
- AggregationTemporality::kDelta));
|