// Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 #include #include #include #include #include #include #include #include #include "opentelemetry/common/spin_lock_mutex.h" #include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation_config.h" #include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" #include "opentelemetry/sdk/metrics/data/metric_data.h" #include "opentelemetry/sdk/metrics/data/point_data.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { namespace metrics { LongHistogramAggregation::LongHistogramAggregation(const AggregationConfig *aggregation_config) { auto ac = static_cast(aggregation_config); if (ac) { point_data_.boundaries_ = ac->boundaries_; } else { point_data_.boundaries_ = {0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0}; } if (ac) { record_min_max_ = ac->record_min_max_; } point_data_.counts_ = std::vector(point_data_.boundaries_.size() + 1, 0); point_data_.sum_ = static_cast(0); point_data_.count_ = 0; point_data_.record_min_max_ = record_min_max_; point_data_.min_ = (std::numeric_limits::max)(); point_data_.max_ = (std::numeric_limits::min)(); } LongHistogramAggregation::LongHistogramAggregation(HistogramPointData &&data) : point_data_{std::move(data)}, record_min_max_{point_data_.record_min_max_} {} LongHistogramAggregation::LongHistogramAggregation(const HistogramPointData &data) : point_data_{data}, record_min_max_{point_data_.record_min_max_} {} void LongHistogramAggregation::Aggregate(int64_t value, const PointAttributes & /* attributes */) noexcept { const std::lock_guard locked(lock_); point_data_.count_ += 1; point_data_.sum_ = nostd::get(point_data_.sum_) + value; if (record_min_max_) { point_data_.min_ = (std::min)(nostd::get(point_data_.min_), value); point_data_.max_ = (std::max)(nostd::get(point_data_.max_), value); } size_t index = BucketBinarySearch(value, point_data_.boundaries_); point_data_.counts_[index] += 1; } std::unique_ptr LongHistogramAggregation::Merge( const Aggregation &delta) const noexcept { auto curr_value = nostd::get(ToPoint()); auto delta_value = nostd::get( (static_cast(delta).ToPoint())); HistogramAggregationConfig agg_config; agg_config.boundaries_ = curr_value.boundaries_; agg_config.record_min_max_ = record_min_max_; LongHistogramAggregation *aggr = new LongHistogramAggregation(&agg_config); HistogramMerge(curr_value, delta_value, aggr->point_data_); return std::unique_ptr(aggr); } std::unique_ptr LongHistogramAggregation::Diff(const Aggregation &next) const noexcept { auto curr_value = nostd::get(ToPoint()); auto next_value = nostd::get( (static_cast(next).ToPoint())); HistogramAggregationConfig agg_config; agg_config.boundaries_ = curr_value.boundaries_; agg_config.record_min_max_ = record_min_max_; LongHistogramAggregation *aggr = new LongHistogramAggregation(&agg_config); HistogramDiff(curr_value, next_value, aggr->point_data_); return std::unique_ptr(aggr); } PointType LongHistogramAggregation::ToPoint() const noexcept { const std::lock_guard locked(lock_); return point_data_; } DoubleHistogramAggregation::DoubleHistogramAggregation(const AggregationConfig *aggregation_config) { auto ac = static_cast(aggregation_config); if (ac) { point_data_.boundaries_ = ac->boundaries_; } else { point_data_.boundaries_ = {0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0}; } if (ac) { record_min_max_ = ac->record_min_max_; } point_data_.counts_ = std::vector(point_data_.boundaries_.size() + 1, 0); point_data_.sum_ = 0.0; point_data_.count_ = 0; point_data_.record_min_max_ = record_min_max_; point_data_.min_ = (std::numeric_limits::max)(); point_data_.max_ = (std::numeric_limits::min)(); } DoubleHistogramAggregation::DoubleHistogramAggregation(HistogramPointData &&data) : point_data_{std::move(data)} {} DoubleHistogramAggregation::DoubleHistogramAggregation(const HistogramPointData &data) : point_data_{data} {} void DoubleHistogramAggregation::Aggregate(double value, const PointAttributes & /* attributes */) noexcept { const std::lock_guard locked(lock_); point_data_.count_ += 1; point_data_.sum_ = nostd::get(point_data_.sum_) + value; if (record_min_max_) { point_data_.min_ = (std::min)(nostd::get(point_data_.min_), value); point_data_.max_ = (std::max)(nostd::get(point_data_.max_), value); } size_t index = BucketBinarySearch(value, point_data_.boundaries_); point_data_.counts_[index] += 1; } std::unique_ptr DoubleHistogramAggregation::Merge( const Aggregation &delta) const noexcept { auto curr_value = nostd::get(ToPoint()); auto delta_value = nostd::get( (static_cast(delta).ToPoint())); HistogramAggregationConfig agg_config; agg_config.boundaries_ = curr_value.boundaries_; agg_config.record_min_max_ = record_min_max_; DoubleHistogramAggregation *aggr = new DoubleHistogramAggregation(&agg_config); HistogramMerge(curr_value, delta_value, aggr->point_data_); return std::unique_ptr(aggr); } std::unique_ptr DoubleHistogramAggregation::Diff( const Aggregation &next) const noexcept { auto curr_value = nostd::get(ToPoint()); auto next_value = nostd::get( (static_cast(next).ToPoint())); HistogramAggregationConfig agg_config; agg_config.boundaries_ = curr_value.boundaries_; agg_config.record_min_max_ = record_min_max_; DoubleHistogramAggregation *aggr = new DoubleHistogramAggregation(&agg_config); HistogramDiff(curr_value, next_value, aggr->point_data_); return std::unique_ptr(aggr); } PointType DoubleHistogramAggregation::ToPoint() const noexcept { const std::lock_guard locked(lock_); return point_data_; } } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE