diff --git a/exporters/otlp/BUILD b/exporters/otlp/BUILD index 01dc83f00b..5e52bfd393 100644 --- a/exporters/otlp/BUILD +++ b/exporters/otlp/BUILD @@ -20,6 +20,7 @@ cc_library( "include/opentelemetry/exporters/otlp/otlp_log_recordable.h", "include/opentelemetry/exporters/otlp/otlp_metric_utils.h", "include/opentelemetry/exporters/otlp/otlp_populate_attribute_utils.h", + "include/opentelemetry/exporters/otlp/otlp_preferred_temporality.h", "include/opentelemetry/exporters/otlp/otlp_recordable.h", "include/opentelemetry/exporters/otlp/otlp_recordable_utils.h", "include/opentelemetry/exporters/otlp/protobuf_include_prefix.h", diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h index b3d5f9b9a7..a56cf8cb55 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h @@ -4,6 +4,7 @@ #pragma once #include "opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h" +#include "opentelemetry/exporters/otlp/otlp_preferred_temporality.h" #include "opentelemetry/sdk/metrics/instruments.h" #include @@ -21,8 +22,8 @@ struct OtlpGrpcMetricExporterOptions : public OtlpGrpcExporterOptions { // Preferred Aggregation Temporality - sdk::metrics::AggregationTemporality aggregation_temporality = - sdk::metrics::AggregationTemporality::kCumulative; + PreferredAggregationTemporality aggregation_temporality = + PreferredAggregationTemporality::kCumulative; }; } // namespace otlp diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h index e37e123097..8aa0ccad21 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h @@ -5,7 +5,7 @@ #include "opentelemetry/exporters/otlp/otlp_environment.h" #include "opentelemetry/exporters/otlp/otlp_http.h" -#include "opentelemetry/sdk/metrics/instruments.h" +#include "opentelemetry/exporters/otlp/otlp_preferred_temporality.h" #include #include @@ -50,8 +50,8 @@ struct OtlpHttpMetricExporterOptions OtlpHeaders http_headers = GetOtlpDefaultMetricsHeaders(); // Preferred Aggregation Temporality - sdk::metrics::AggregationTemporality aggregation_temporality = - sdk::metrics::AggregationTemporality::kCumulative; + PreferredAggregationTemporality aggregation_temporality = + PreferredAggregationTemporality::kCumulative; #ifdef ENABLE_ASYNC_EXPORT // Concurrent requests diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_metric_utils.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_metric_utils.h index 8efbad2453..1adca861d8 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_metric_utils.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_metric_utils.h @@ -9,6 +9,7 @@ #include "opentelemetry/proto/metrics/v1/metrics.pb.h" #include "opentelemetry/proto/resource/v1/resource.pb.h" +#include "opentelemetry/exporters/otlp/otlp_preferred_temporality.h" #include "opentelemetry/exporters/otlp/protobuf_include_suffix.h" #include "opentelemetry/sdk/metrics/export/metric_producer.h" @@ -52,11 +53,13 @@ class OtlpMetricUtils proto::collector::metrics::v1::ExportMetricsServiceRequest *request) noexcept; static sdk::metrics::AggregationTemporalitySelector ChooseTemporalitySelector( - sdk::metrics::AggregationTemporality preferred_aggregation_temporality) noexcept; + PreferredAggregationTemporality preferred_aggregation_temporality) noexcept; static sdk::metrics::AggregationTemporality DeltaTemporalitySelector( sdk::metrics::InstrumentType instrument_type) noexcept; static sdk::metrics::AggregationTemporality CumulativeTemporalitySelector( sdk::metrics::InstrumentType instrument_type) noexcept; + static sdk::metrics::AggregationTemporality LowMemoryTemporalitySelector( + sdk::metrics::InstrumentType instrument_type) noexcept; }; } // namespace otlp diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_preferred_temporality.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_preferred_temporality.h new file mode 100644 index 0000000000..d9e4013fd5 --- /dev/null +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_preferred_temporality.h @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace otlp +{ + +enum class PreferredAggregationTemporality +{ + kUnspecified, + kDelta, + kCumulative, + kLowMemory, +}; + +} +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/otlp/src/otlp_metric_utils.cc b/exporters/otlp/src/otlp_metric_utils.cc index f642bbf85e..50c5fdd9cc 100644 --- a/exporters/otlp/src/otlp_metric_utils.cc +++ b/exporters/otlp/src/otlp_metric_utils.cc @@ -247,13 +247,17 @@ void OtlpMetricUtils::PopulateRequest( } sdk::metrics::AggregationTemporalitySelector OtlpMetricUtils::ChooseTemporalitySelector( - sdk::metrics::AggregationTemporality preferred_aggregation_temporality) noexcept + PreferredAggregationTemporality preferred_aggregation_temporality) noexcept { - if (preferred_aggregation_temporality == sdk::metrics::AggregationTemporality::kDelta) + if (preferred_aggregation_temporality == PreferredAggregationTemporality::kDelta) { return DeltaTemporalitySelector; } - return CumulativeTemporalitySelector; + else if (preferred_aggregation_temporality == PreferredAggregationTemporality::kCumulative) + { + return CumulativeTemporalitySelector; + } + return LowMemoryTemporalitySelector; } sdk::metrics::AggregationTemporality OtlpMetricUtils::DeltaTemporalitySelector( @@ -279,6 +283,22 @@ sdk::metrics::AggregationTemporality OtlpMetricUtils::CumulativeTemporalitySelec return sdk::metrics::AggregationTemporality::kCumulative; } +sdk::metrics::AggregationTemporality OtlpMetricUtils::LowMemoryTemporalitySelector( + sdk::metrics::InstrumentType instrument_type) noexcept +{ + switch (instrument_type) + { + case sdk::metrics::InstrumentType::kCounter: + case sdk::metrics::InstrumentType::kHistogram: + return sdk::metrics::AggregationTemporality::kDelta; + case sdk::metrics::InstrumentType::kObservableCounter: + case sdk::metrics::InstrumentType::kObservableGauge: + case sdk::metrics::InstrumentType::kUpDownCounter: + case sdk::metrics::InstrumentType::kObservableUpDownCounter: + return sdk::metrics::AggregationTemporality::kCumulative; + } + return sdk::metrics::AggregationTemporality::kUnspecified; +} } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/otlp/test/otlp_http_metric_exporter_test.cc b/exporters/otlp/test/otlp_http_metric_exporter_test.cc index 97586b101c..ed7c4dba30 100644 --- a/exporters/otlp/test/otlp_http_metric_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_metric_exporter_test.cc @@ -11,6 +11,7 @@ #include "opentelemetry/proto/collector/metrics/v1/metrics_service.pb.h" +#include "opentelemetry/exporters/otlp/otlp_metric_utils.h" #include "opentelemetry/exporters/otlp/protobuf_include_suffix.h" #include "opentelemetry/common/key_value_iterable_view.h" @@ -976,6 +977,78 @@ TEST_F(OtlpHttpMetricExporterTestPeer, CheckDefaultTemporality) } #endif +// Test Preferred aggregtion temporality selection +TEST_F(OtlpHttpMetricExporterTestPeer, PreferredAggergationTemporality) +{ + // Cummulative aggregation selector : use cummulative aggregation for all instruments. + std::unique_ptr exporter(new OtlpHttpMetricExporter()); + EXPECT_EQ(GetOptions(exporter).aggregation_temporality, + PreferredAggregationTemporality::kCumulative); + auto cumm_selector = + OtlpMetricUtils::ChooseTemporalitySelector(GetOptions(exporter).aggregation_temporality); + EXPECT_EQ(cumm_selector(opentelemetry::sdk::metrics::InstrumentType::kCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ(cumm_selector(opentelemetry::sdk::metrics::InstrumentType::kHistogram), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ(cumm_selector(opentelemetry::sdk::metrics::InstrumentType::kUpDownCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ(cumm_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ(cumm_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableGauge), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ(cumm_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableUpDownCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + + // LowMemory aggregation selector use: + // - cummulative aggregtion for Counter and Histogram + // - delta aggregation for up-down counter, observable counter, observable gauge, observable + // up-down counter + OtlpHttpMetricExporterOptions opts2; + opts2.aggregation_temporality = PreferredAggregationTemporality::kLowMemory; + std::unique_ptr exporter2(new OtlpHttpMetricExporter(opts2)); + EXPECT_EQ(GetOptions(exporter2).aggregation_temporality, + PreferredAggregationTemporality::kLowMemory); + auto lowmemory_selector = + OtlpMetricUtils::ChooseTemporalitySelector(GetOptions(exporter2).aggregation_temporality); + EXPECT_EQ(lowmemory_selector(opentelemetry::sdk::metrics::InstrumentType::kCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kDelta); + EXPECT_EQ(lowmemory_selector(opentelemetry::sdk::metrics::InstrumentType::kHistogram), + opentelemetry::sdk::metrics::AggregationTemporality::kDelta); + + EXPECT_EQ(lowmemory_selector(opentelemetry::sdk::metrics::InstrumentType::kUpDownCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ(lowmemory_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ(lowmemory_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableGauge), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ( + lowmemory_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableUpDownCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + + // Delta aggregation selector use: + // - delta aggregtion for Counter, Histogram, Observable Counter, Observable Gauge + // - cummulative aggregation for up-down counter, observable up-down counter + OtlpHttpMetricExporterOptions opts3; + opts3.aggregation_temporality = PreferredAggregationTemporality::kDelta; + std::unique_ptr exporter3(new OtlpHttpMetricExporter(opts3)); + EXPECT_EQ(GetOptions(exporter3).aggregation_temporality, PreferredAggregationTemporality::kDelta); + auto delta_selector = + OtlpMetricUtils::ChooseTemporalitySelector(GetOptions(exporter3).aggregation_temporality); + EXPECT_EQ(delta_selector(opentelemetry::sdk::metrics::InstrumentType::kCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kDelta); + EXPECT_EQ(delta_selector(opentelemetry::sdk::metrics::InstrumentType::kHistogram), + opentelemetry::sdk::metrics::AggregationTemporality::kDelta); + EXPECT_EQ(delta_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kDelta); + EXPECT_EQ(delta_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableGauge), + opentelemetry::sdk::metrics::AggregationTemporality::kDelta); + + EXPECT_EQ(delta_selector(opentelemetry::sdk::metrics::InstrumentType::kUpDownCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); + EXPECT_EQ(delta_selector(opentelemetry::sdk::metrics::InstrumentType::kObservableUpDownCounter), + opentelemetry::sdk::metrics::AggregationTemporality::kCumulative); +} + } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE