diff --git a/CHANGELOG.md b/CHANGELOG.md index 11ba426024..e8379620fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ Increment the: [#2449](https://github.com/open-telemetry/opentelemetry-cpp/pull/2449) * [BUILD] Introduce CXX 20 CI pipeline for MSVC/Windows [#2450](https://github.com/open-telemetry/opentelemetry-cpp/pull/2450) +* [EXPORTER] Set `is_monotonic` flag for Observable Counters + [#2478](https://github.com/open-telemetry/opentelemetry-cpp/pull/2478) Important changes: diff --git a/exporters/otlp/src/otlp_metric_utils.cc b/exporters/otlp/src/otlp_metric_utils.cc index ed1620a56c..53e84e7966 100644 --- a/exporters/otlp/src/otlp_metric_utils.cc +++ b/exporters/otlp/src/otlp_metric_utils.cc @@ -54,8 +54,9 @@ void OtlpMetricUtils::ConvertSumMetric(const metric_sdk::MetricData &metric_data { sum->set_aggregation_temporality( GetProtoAggregationTemporality(metric_data.aggregation_temporality)); - sum->set_is_monotonic(metric_data.instrument_descriptor.type_ == - metric_sdk::InstrumentType::kCounter); + sum->set_is_monotonic( + (metric_data.instrument_descriptor.type_ == metric_sdk::InstrumentType::kCounter) || + (metric_data.instrument_descriptor.type_ == metric_sdk::InstrumentType::kObservableCounter)); auto start_ts = metric_data.start_ts.time_since_epoch().count(); auto ts = metric_data.end_ts.time_since_epoch().count(); for (auto &point_data_with_attributes : metric_data.point_data_attr_) diff --git a/exporters/otlp/test/otlp_metrics_serialization_test.cc b/exporters/otlp/test/otlp_metrics_serialization_test.cc index ac0f717b25..b945cb28fe 100644 --- a/exporters/otlp/test/otlp_metrics_serialization_test.cc +++ b/exporters/otlp/test/otlp_metrics_serialization_test.cc @@ -130,6 +130,66 @@ static metrics_sdk::MetricData CreateObservableGaugeAggregationData() return data; } +static metrics_sdk::MetricData CreateObservableCounterAggregationData() +{ + metrics_sdk::MetricData data; + data.start_ts = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + metrics_sdk::InstrumentDescriptor inst_desc = { + "ObservableCounter", "test description", "test unit", + metrics_sdk::InstrumentType::kObservableCounter, metrics_sdk::InstrumentValueType::kDouble}; + metrics_sdk::SumPointData s_data_1, s_data_2; + s_data_1.value_ = 1.23; + s_data_2.value_ = 4.56; + + data.aggregation_temporality = metrics_sdk::AggregationTemporality::kCumulative; + data.end_ts = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + data.instrument_descriptor = inst_desc; + metrics_sdk::PointDataAttributes point_data_attr_1, point_data_attr_2; + point_data_attr_1.attributes = {{"key1", "value1"}}; + point_data_attr_1.point_data = s_data_1; + + point_data_attr_2.attributes = {{"key2", "value2"}}; + point_data_attr_2.point_data = s_data_2; + std::vector point_data_attr; + point_data_attr.push_back(point_data_attr_1); + point_data_attr.push_back(point_data_attr_2); + data.point_data_attr_ = std::move(point_data_attr); + return data; +} + +static metrics_sdk::MetricData CreateObservableUpDownCounterAggregationData() +{ + metrics_sdk::MetricData data; + data.start_ts = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + metrics_sdk::InstrumentDescriptor inst_desc = { + "ObservableUpDownCounter", "test description", "test unit", + metrics_sdk::InstrumentType::kObservableUpDownCounter, + metrics_sdk::InstrumentValueType::kDouble}; + metrics_sdk::SumPointData s_data_1, s_data_2, s_data_3; + s_data_1.value_ = 1.23; + s_data_2.value_ = 4.56; + s_data_3.value_ = 2.34; + + data.aggregation_temporality = metrics_sdk::AggregationTemporality::kCumulative; + data.end_ts = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + data.instrument_descriptor = inst_desc; + metrics_sdk::PointDataAttributes point_data_attr_1, point_data_attr_2, point_data_attr_3; + point_data_attr_1.attributes = {{"key1", "value1"}}; + point_data_attr_1.point_data = s_data_1; + + point_data_attr_2.attributes = {{"key2", "value2"}}; + point_data_attr_2.point_data = s_data_2; + + point_data_attr_3.attributes = {{"key3", "value3"}}; + point_data_attr_3.point_data = s_data_3; + std::vector point_data_attr; + point_data_attr.push_back(point_data_attr_1); + point_data_attr.push_back(point_data_attr_2); + point_data_attr.push_back(point_data_attr_3); + data.point_data_attr_ = std::move(point_data_attr); + return data; +} + TEST(OtlpMetricSerializationTest, Counter) { metrics_sdk::MetricData data = CreateSumAggregationData(); @@ -191,6 +251,37 @@ TEST(OtlpMetricSerializationTest, ObservableGauge) EXPECT_EQ(1, 1); } +TEST(OtlpMetricSerializationTest, ObservableCounter) +{ + metrics_sdk::MetricData data = CreateObservableCounterAggregationData(); + opentelemetry::proto::metrics::v1::Sum sum; + otlp_exporter::OtlpMetricUtils::ConvertSumMetric(data, &sum); + EXPECT_EQ(sum.aggregation_temporality(), + proto::metrics::v1::AggregationTemporality::AGGREGATION_TEMPORALITY_CUMULATIVE); + EXPECT_EQ(sum.is_monotonic(), true); + EXPECT_EQ(sum.data_points_size(), 2); + EXPECT_EQ(sum.data_points(0).as_double(), 1.23); + EXPECT_EQ(sum.data_points(1).as_double(), 4.56); + + EXPECT_EQ(1, 1); +} + +TEST(OtlpMetricSerializationTest, ObservableUpDownCounter) +{ + metrics_sdk::MetricData data = CreateObservableUpDownCounterAggregationData(); + opentelemetry::proto::metrics::v1::Sum sum; + otlp_exporter::OtlpMetricUtils::ConvertSumMetric(data, &sum); + EXPECT_EQ(sum.aggregation_temporality(), + proto::metrics::v1::AggregationTemporality::AGGREGATION_TEMPORALITY_CUMULATIVE); + EXPECT_EQ(sum.is_monotonic(), false); + EXPECT_EQ(sum.data_points_size(), 3); + EXPECT_EQ(sum.data_points(0).as_double(), 1.23); + EXPECT_EQ(sum.data_points(1).as_double(), 4.56); + EXPECT_EQ(sum.data_points(2).as_double(), 2.34); + + EXPECT_EQ(1, 1); +} + } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE