diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h new file mode 100644 index 0000000000..3bb133ac15 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/nostd/string_view.h" +# include "opentelemetry/sdk/metrics/data/metric_data.h" +# include "opentelemetry/sdk/metrics/data/point_data.h" +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class InstrumentMonotonicityAwareAggregation +{ +public: + InstrumentMonotonicityAwareAggregation(bool is_monotonic) : is_monotonic_(is_monotonic) {} + bool IsMonotonic() { return is_monotonic_; } + +private: + bool is_monotonic_; +}; + +class Aggregation +{ +public: + virtual void Aggregate(long value, const PointAttributes &attributes = {}) noexcept = 0; + + virtual void Aggregate(double value, const PointAttributes &attributes = {}) noexcept = 0; + + virtual PointType Collect() noexcept = 0; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h new file mode 100644 index 0000000000..cad43d7aa5 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/common/spin_lock_mutex.h" +# include "opentelemetry/sdk/metrics/aggregation/aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/drop_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/sum_aggregation.h" +# include "opentelemetry/sdk/metrics/instruments.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class DefaultAggregation +{ +public: + static std::unique_ptr CreateAggregation( + const opentelemetry::sdk::metrics::InstrumentDescriptor &instrument_descriptor) + { + switch (instrument_descriptor.type_) + { + case InstrumentType::kCounter: + case InstrumentType::kUpDownCounter: + case InstrumentType::kObservableUpDownCounter: + return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) + ? std::move(std::unique_ptr(new LongSumAggregation(true))) + : std::move(std::unique_ptr(new DoubleSumAggregation(true))); + break; + case InstrumentType::kHistogram: + return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) + ? std::move(std::unique_ptr(new LongHistogramAggregation())) + : std::move(std::unique_ptr(new DoubleHistogramAggregation())); + break; + case InstrumentType::kObservableGauge: + return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) + ? std::move(std::unique_ptr(new LongLastValueAggregation())) + : std::move(std::unique_ptr(new DoubleLastValueAggregation())); + break; + default: + return std::move(std::unique_ptr(new DropAggregation())); + }; + } +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h new file mode 100644 index 0000000000..0af5dd43a5 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/common/spin_lock_mutex.h" +# include "opentelemetry/sdk/metrics/aggregation/aggregation.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +class DropAggregation : public Aggregation +{ +public: + DropAggregation() = default; + + void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} + + void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} + + PointType Collect() noexcept override { return DropPointData(); } +}; +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h new file mode 100644 index 0000000000..5a66ecb243 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h @@ -0,0 +1,72 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/common/spin_lock_mutex.h" +# include "opentelemetry/sdk/metrics/aggregation/aggregation.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +template +static inline void PopulateHistogramDataPoint(HistogramPointData &histogram, + opentelemetry::common::SystemTimestamp epoch_nanos, + T sum, + uint64_t count, + std::vector &counts, + std::vector boundaries) +{ + histogram.epoch_nanos_ = epoch_nanos; + histogram.boundaries_ = boundaries; + histogram.sum_ = sum; + histogram.counts_ = counts; + histogram.count_ = count; +} + +class LongHistogramAggregation : public Aggregation +{ +public: + LongHistogramAggregation(); + + void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; + + void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} + + PointType Collect() noexcept override; + +private: + opentelemetry::common::SpinLockMutex lock_; + std::vector boundaries_; + long sum_; + std::vector counts_; + uint64_t count_; +}; + +class DoubleHistogramAggregation : public Aggregation +{ +public: + DoubleHistogramAggregation(); + + void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} + + void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; + + PointType Collect() noexcept override; + +private: + opentelemetry::common::SpinLockMutex lock_; + std::vector boundaries_; + double sum_; + std::vector counts_; + uint64_t count_; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h new file mode 100644 index 0000000000..092a0df30e --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h @@ -0,0 +1,53 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/common/spin_lock_mutex.h" +# include "opentelemetry/sdk/metrics/aggregation/aggregation.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class LongLastValueAggregation : public Aggregation +{ +public: + LongLastValueAggregation(); + + void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; + + void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} + + PointType Collect() noexcept override; + +private: + opentelemetry::common::SpinLockMutex lock_; + long value_; + bool is_lastvalue_valid_; +}; + +class DoubleLastValueAggregation : public Aggregation +{ +public: + DoubleLastValueAggregation(); + + void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} + + void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; + + PointType Collect() noexcept override; + +private: + opentelemetry::common::SpinLockMutex lock_; + double value_; + bool is_lastvalue_valid_; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h new file mode 100644 index 0000000000..c8b2eff33c --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h @@ -0,0 +1,68 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/common/spin_lock_mutex.h" +# include "opentelemetry/sdk/metrics/aggregation/aggregation.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +template +static inline void PopulateSumPointData(SumPointData &sum, + opentelemetry::common::SystemTimestamp start_ts, + opentelemetry::common::SystemTimestamp end_ts, + T value, + bool is_monotonic) +{ + sum.start_epoch_nanos_ = start_ts; + sum.end_epoch_nanos_ = end_ts; + sum.value_ = value; + sum.is_monotonic_ = is_monotonic; + sum.aggregation_temporarily_ = AggregationTemporarily::kDelta; +} + +class LongSumAggregation : public Aggregation, InstrumentMonotonicityAwareAggregation +{ +public: + LongSumAggregation(bool is_monotonic); + + void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; + + void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} + + PointType Collect() noexcept override; + +private: + opentelemetry::common::SpinLockMutex lock_; + opentelemetry::common::SystemTimestamp start_epoch_nanos_; + long sum_; +}; + +class DoubleSumAggregation : public Aggregation, InstrumentMonotonicityAwareAggregation +{ +public: + DoubleSumAggregation(bool is_monotonic); + + void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} + + void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; + + PointType Collect() noexcept override; + +private: + opentelemetry::common::SpinLockMutex lock_; + opentelemetry::common::SystemTimestamp start_epoch_nanos_; + double sum_; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregator/aggregator.h b/sdk/include/opentelemetry/sdk/metrics/aggregator/aggregator.h index 73d7d20e71..416cea5adf 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregator/aggregator.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregator/aggregator.h @@ -3,17 +3,15 @@ #pragma once #ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/aggregation/aggregation.h" # include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { namespace metrics { - class Aggregator -{ - // TBD -}; +{}; class NoOpAggregator : public Aggregator { diff --git a/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h b/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h new file mode 100644 index 0000000000..cb7bc4cf80 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/nostd/variant.h" +# include "opentelemetry/sdk/common/attribute_utils.h" +# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" +# include "opentelemetry/sdk/metrics/data/point_data.h" +# include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/resource/resource.h" +# include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +using PointAttributes = opentelemetry::sdk::common::AttributeMap; +using PointType = opentelemetry::nostd:: + variant; + +class MetricData +{ +public: + opentelemetry::sdk::resource::Resource *resource_; + opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary *instrumentation_library_; + PointAttributes attributes_; + InstrumentDescriptor instrument_descriptor; + PointType point_data_; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/data/point_data.h b/sdk/include/opentelemetry/sdk/metrics/data/point_data.h new file mode 100644 index 0000000000..e95a329e44 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/data/point_data.h @@ -0,0 +1,62 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/common/timestamp.h" +# include "opentelemetry/nostd/variant.h" +# include "opentelemetry/version.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +using ValueType = nostd::variant; +using ListType = nostd::variant, std::vector>; + +enum class AggregationTemporarily +{ + kUnspecified, + kDelta, + kCummulative +}; + +class SumPointData +{ +public: + opentelemetry::common::SystemTimestamp start_epoch_nanos_; + opentelemetry::common::SystemTimestamp end_epoch_nanos_; + ValueType value_; + AggregationTemporarily aggregation_temporarily_; + bool is_monotonic_; +}; + +class LastValuePointData +{ +public: + opentelemetry::common::SystemTimestamp epoch_nanos_; + bool is_lastvalue_valid_; + ValueType value_; +}; + +class HistogramPointData +{ +public: + opentelemetry::common::SystemTimestamp epoch_nanos_; + ListType boundaries_; + ValueType sum_; + std::vector counts_; + uint64_t count_; +}; + +class DropPointData +{}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/instruments.h b/sdk/include/opentelemetry/sdk/metrics/instruments.h index 8d101090c7..88d432a136 100644 --- a/sdk/include/opentelemetry/sdk/metrics/instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/instruments.h @@ -33,7 +33,7 @@ struct InstrumentDescriptor std::string description_; std::string unit_; InstrumentType type_; - InstrumentValueType valueType_; + InstrumentValueType value_type_; }; /*class InstrumentSelector { diff --git a/sdk/include/opentelemetry/sdk/metrics/view/aggregation.h b/sdk/include/opentelemetry/sdk/metrics/view/aggregation.h deleted file mode 100644 index de851e10fa..0000000000 --- a/sdk/include/opentelemetry/sdk/metrics/view/aggregation.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once -#ifndef ENABLE_METRICS_PREVIEW - -# include -# include "opentelemetry/sdk/metrics/aggregator/aggregator.h" -# include "opentelemetry/sdk/metrics/instruments.h" -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace metrics -{ -class Aggregation -{ -public: - virtual ~Aggregation() = default; - virtual opentelemetry::sdk::metrics::Aggregator &CreateAggregator( - opentelemetry::sdk::metrics::InstrumentDescriptor instrument_descriptor) noexcept = 0; -}; - -class NoOpAggregation : public Aggregation -{ - - opentelemetry::sdk::metrics::Aggregator &CreateAggregator( - opentelemetry::sdk::metrics::InstrumentDescriptor instrument_descriptor) noexcept override - { - static opentelemetry::sdk::metrics::NoOpAggregator noop_aggregator; - return noop_aggregator; - } -}; - -class DefaultAggregation : public Aggregation -{ - - opentelemetry::sdk::metrics::Aggregator &CreateAggregator( - opentelemetry::sdk::metrics::InstrumentDescriptor instrument_descriptor) noexcept override - { - // TBD - This shouldn't return noop_aggregator - static opentelemetry::sdk::metrics::NoOpAggregator noop_aggregator; - return noop_aggregator; - } -}; - -} // namespace metrics -} // namespace sdk -OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/view/view.h b/sdk/include/opentelemetry/sdk/metrics/view/view.h index c131b4fc04..4d1119d894 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/view.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/view.h @@ -4,7 +4,7 @@ #pragma once #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/nostd/string_view.h" -# include "opentelemetry/sdk/metrics/view/aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" # include "opentelemetry/sdk/metrics/view/attributes_processor.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -23,8 +23,7 @@ class View View(const std::string &name, const std::string &description = "", std::unique_ptr aggregation = - std::unique_ptr( - new opentelemetry::sdk::metrics::DefaultAggregation()), + std::unique_ptr(new DropAggregation()), std::unique_ptr attributes_processor = std::unique_ptr( new opentelemetry::sdk::metrics::DefaultAttributesProcessor())) diff --git a/sdk/src/metrics/CMakeLists.txt b/sdk/src/metrics/CMakeLists.txt index d1d7ae97bc..72f9031e2a 100644 --- a/sdk/src/metrics/CMakeLists.txt +++ b/sdk/src/metrics/CMakeLists.txt @@ -1,4 +1,8 @@ -add_library(opentelemetry_metrics meter_provider.cc meter.cc meter_context.cc) +add_library( + opentelemetry_metrics + meter_provider.cc meter.cc meter_context.cc + aggregation/histogram_aggregation.cc aggregation/lastvalue_aggregation.cc + aggregation/sum_aggregation.cc) set_target_properties(opentelemetry_metrics PROPERTIES EXPORT_NAME metrics) diff --git a/sdk/src/metrics/aggregation/histogram_aggregation.cc b/sdk/src/metrics/aggregation/histogram_aggregation.cc new file mode 100644 index 0000000000..2ebe3715bb --- /dev/null +++ b/sdk/src/metrics/aggregation/histogram_aggregation.cc @@ -0,0 +1,80 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" +# include "opentelemetry/version.h" + +# include +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +LongHistogramAggregation::LongHistogramAggregation() + : boundaries_{0l, 5l, 10l, 25l, 50l, 75l, 100l, 250l, 500l, 1000l}, + counts_(boundaries_.size() + 1, 0), + sum_(0l), + count_(0) +{} + +void LongHistogramAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept +{ + const std::lock_guard locked(lock_); + count_ += 1; + sum_ += value; + for (auto it = boundaries_.begin(); it != boundaries_.end(); ++it) + { + if (value < *it) + { + counts_[std::distance(boundaries_.begin(), it)] += 1; + return; + } + } +} + +PointType LongHistogramAggregation::Collect() noexcept +{ + HistogramPointData point_data; + auto epoch_nanos = std::chrono::system_clock::now(); + const std::lock_guard locked(lock_); + PopulateHistogramDataPoint(point_data, epoch_nanos, sum_, count_, counts_, boundaries_); + return point_data; +} + +DoubleHistogramAggregation::DoubleHistogramAggregation() + : boundaries_{0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0}, + counts_(boundaries_.size() + 1, 0), + sum_(0.0), + count_(0) +{} + +void DoubleHistogramAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept +{ + const std::lock_guard locked(lock_); + count_ += 1; + sum_ += value; + for (auto it = boundaries_.begin(); it != boundaries_.end(); ++it) + { + if (value < *it) + { + counts_[std::distance(boundaries_.begin(), it)] += 1; + return; + } + } +} + +PointType DoubleHistogramAggregation::Collect() noexcept +{ + HistogramPointData point_data; + auto epoch_nanos = std::chrono::system_clock::now(); + const std::lock_guard locked(lock_); + PopulateHistogramDataPoint(point_data, epoch_nanos, sum_, count_, counts_, boundaries_); + return point_data; +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/src/metrics/aggregation/lastvalue_aggregation.cc b/sdk/src/metrics/aggregation/lastvalue_aggregation.cc new file mode 100644 index 0000000000..290b526344 --- /dev/null +++ b/sdk/src/metrics/aggregation/lastvalue_aggregation.cc @@ -0,0 +1,61 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h" +# include "opentelemetry/common/timestamp.h" +# include "opentelemetry/version.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +LongLastValueAggregation::LongLastValueAggregation() : is_lastvalue_valid_(false) {} + +void LongLastValueAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept +{ + const std::lock_guard locked(lock_); + is_lastvalue_valid_ = true; + value_ = value; +} + +PointType LongLastValueAggregation::Collect() noexcept +{ + const std::lock_guard locked(lock_); + if (!is_lastvalue_valid_) + { + return LastValuePointData{ + opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()), false, 0l}; + } + return LastValuePointData{ + opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()), true, value_}; +} + +DoubleLastValueAggregation::DoubleLastValueAggregation() : is_lastvalue_valid_(false) {} + +void DoubleLastValueAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept +{ + const std::lock_guard locked(lock_); + is_lastvalue_valid_ = true; + value_ = value; +} + +PointType DoubleLastValueAggregation::Collect() noexcept +{ + const std::lock_guard locked(lock_); + if (!is_lastvalue_valid_) + { + return LastValuePointData{ + opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()), false, 0.0}; + } + return LastValuePointData{ + opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()), true, value_}; +} +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/src/metrics/aggregation/sum_aggregation.cc b/sdk/src/metrics/aggregation/sum_aggregation.cc new file mode 100644 index 0000000000..e0d1330f68 --- /dev/null +++ b/sdk/src/metrics/aggregation/sum_aggregation.cc @@ -0,0 +1,69 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/aggregation/sum_aggregation.h" +# include "opentelemetry/version.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +LongSumAggregation::LongSumAggregation(bool is_monotonic) + : InstrumentMonotonicityAwareAggregation(is_monotonic), + start_epoch_nanos_(opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())), + sum_(0l) +{} + +void LongSumAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept +{ + const std::lock_guard locked(lock_); + sum_ += value; +} + +PointType LongSumAggregation::Collect() noexcept +{ + opentelemetry::common::SystemTimestamp current_ts(std::chrono::system_clock::now()); + SumPointData sum; + { + const std::lock_guard locked(lock_); + PopulateSumPointData(sum, start_epoch_nanos_, current_ts, sum_, IsMonotonic()); + start_epoch_nanos_ = current_ts; + sum_ = 0; + } + return sum; +} + +DoubleSumAggregation::DoubleSumAggregation(bool is_monotonic) + : InstrumentMonotonicityAwareAggregation(is_monotonic), + start_epoch_nanos_(opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())), + sum_(0L) +{} + +void DoubleSumAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept +{ + const std::lock_guard locked(lock_); + sum_ += value; +} + +PointType DoubleSumAggregation::Collect() noexcept +{ + opentelemetry::common::SystemTimestamp current_ts(std::chrono::system_clock::now()); + SumPointData sum; + { + const std::lock_guard locked(lock_); + PopulateSumPointData(sum, start_epoch_nanos_, current_ts, sum_, IsMonotonic()); + start_epoch_nanos_ = current_ts; + sum_ = 0; + } + return sum; +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/test/metrics/BUILD b/sdk/test/metrics/BUILD index 1e4df5a481..97ed43633a 100644 --- a/sdk/test/metrics/BUILD +++ b/sdk/test/metrics/BUILD @@ -16,6 +16,38 @@ cc_test( ], ) +cc_test( + name = "view_registry_test", + srcs = [ + "view_registry_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "aggregation_test", + srcs = [ + "aggregation_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "attributes_processor_test", srcs = [ diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index 36deef5f05..3fc065220f 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -1,4 +1,4 @@ -foreach(testname meter_provider_sdk_test view_registry_test +foreach(testname meter_provider_sdk_test view_registry_test aggregation_test attributes_processor_test) add_executable(${testname} "${testname}.cc") target_link_libraries( diff --git a/sdk/test/metrics/aggregation_test.cc b/sdk/test/metrics/aggregation_test.cc new file mode 100644 index 0000000000..ec753111ff --- /dev/null +++ b/sdk/test/metrics/aggregation_test.cc @@ -0,0 +1,122 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/sum_aggregation.h" + +# include "opentelemetry/nostd/variant.h" + +using namespace opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +TEST(Aggregation, LongSumAggregation) +{ + LongSumAggregation aggr(true); + auto data = aggr.Collect(); + ASSERT_TRUE(nostd::holds_alternative(data)); + auto sum_data = nostd::get(data); + ASSERT_TRUE(nostd::holds_alternative(sum_data.value_)); + EXPECT_EQ(nostd::get(sum_data.value_), 0l); + EXPECT_EQ(sum_data.is_monotonic_, true); + EXPECT_NO_THROW(aggr.Aggregate(12l, {})); + EXPECT_NO_THROW(aggr.Aggregate(0l, {})); + sum_data = nostd::get(aggr.Collect()); + EXPECT_EQ(nostd::get(sum_data.value_), 12l); +} + +TEST(Aggregation, DoubleSumAggregation) +{ + DoubleSumAggregation aggr(true); + auto data = aggr.Collect(); + ASSERT_TRUE(nostd::holds_alternative(data)); + auto sum_data = nostd::get(data); + ASSERT_TRUE(nostd::holds_alternative(sum_data.value_)); + EXPECT_EQ(nostd::get(sum_data.value_), 0); + EXPECT_EQ(sum_data.is_monotonic_, true); + EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); + EXPECT_NO_THROW(aggr.Aggregate(1.0, {})); + sum_data = nostd::get(aggr.Collect()); + EXPECT_EQ(nostd::get(sum_data.value_), 13.0); +} + +TEST(Aggregation, LongLastValueAggregation) +{ + LongLastValueAggregation aggr; + auto data = aggr.Collect(); + ASSERT_TRUE(nostd::holds_alternative(data)); + auto lastvalue_data = nostd::get(data); + ASSERT_TRUE(nostd::holds_alternative(lastvalue_data.value_)); + EXPECT_EQ(lastvalue_data.is_lastvalue_valid_, false); + EXPECT_NO_THROW(aggr.Aggregate(12l, {})); + EXPECT_NO_THROW(aggr.Aggregate(1l, {})); + lastvalue_data = nostd::get(aggr.Collect()); + EXPECT_EQ(nostd::get(lastvalue_data.value_), 1.0); +} + +TEST(Aggregation, DoubleLastValueAggregation) +{ + DoubleLastValueAggregation aggr; + auto data = aggr.Collect(); + ASSERT_TRUE(nostd::holds_alternative(data)); + auto lastvalue_data = nostd::get(data); + ASSERT_TRUE(nostd::holds_alternative(lastvalue_data.value_)); + EXPECT_EQ(lastvalue_data.is_lastvalue_valid_, false); + EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); + EXPECT_NO_THROW(aggr.Aggregate(1.0, {})); + lastvalue_data = nostd::get(aggr.Collect()); + EXPECT_EQ(nostd::get(lastvalue_data.value_), 1.0); +} + +TEST(Aggregation, LongHistogramAggregation) +{ + LongHistogramAggregation aggr; + auto data = aggr.Collect(); + ASSERT_TRUE(nostd::holds_alternative(data)); + auto histogram_data = nostd::get(data); + ASSERT_TRUE(nostd::holds_alternative(histogram_data.sum_)); + ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); + EXPECT_EQ(nostd::get(histogram_data.sum_), 0); + EXPECT_EQ(histogram_data.count_, 0); + EXPECT_NO_THROW(aggr.Aggregate(12l, {})); // lies in fourth bucket + EXPECT_NO_THROW(aggr.Aggregate(100l, {})); // lies in eight bucket + histogram_data = nostd::get(aggr.Collect()); + EXPECT_EQ(nostd::get(histogram_data.sum_), 112); + EXPECT_EQ(histogram_data.count_, 2); + EXPECT_EQ(histogram_data.counts_[3], 1); + EXPECT_EQ(histogram_data.counts_[7], 1); + EXPECT_NO_THROW(aggr.Aggregate(13l, {})); // lies in fourth bucket + EXPECT_NO_THROW(aggr.Aggregate(252l, {})); // lies in ninth bucket + histogram_data = nostd::get(aggr.Collect()); + EXPECT_EQ(histogram_data.count_, 4); + EXPECT_EQ(histogram_data.counts_[3], 2); + EXPECT_EQ(histogram_data.counts_[8], 1); +} + +TEST(Aggregation, DoubleHistogramAggregation) +{ + DoubleHistogramAggregation aggr; + auto data = aggr.Collect(); + ASSERT_TRUE(nostd::holds_alternative(data)); + auto histogram_data = nostd::get(data); + ASSERT_TRUE(nostd::holds_alternative(histogram_data.sum_)); + ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); + EXPECT_EQ(nostd::get(histogram_data.sum_), 0); + EXPECT_EQ(histogram_data.count_, 0); + EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); // lies in fourth bucket + EXPECT_NO_THROW(aggr.Aggregate(100.0, {})); // lies in eight bucket + histogram_data = nostd::get(aggr.Collect()); + EXPECT_EQ(nostd::get(histogram_data.sum_), 112); + EXPECT_EQ(histogram_data.count_, 2); + EXPECT_EQ(histogram_data.counts_[3], 1); + EXPECT_EQ(histogram_data.counts_[7], 1); + EXPECT_NO_THROW(aggr.Aggregate(13.0, {})); // lies in fourth bucket + EXPECT_NO_THROW(aggr.Aggregate(252.0, {})); // lies in ninth bucket + histogram_data = nostd::get(aggr.Collect()); + EXPECT_EQ(histogram_data.count_, 4); + EXPECT_EQ(histogram_data.counts_[3], 2); + EXPECT_EQ(histogram_data.counts_[8], 1); + EXPECT_EQ(nostd::get(histogram_data.sum_), 377); +} +#endif \ No newline at end of file