From 0f5b25cefcdaab4547b01a6f150ff7a4faf52c5c Mon Sep 17 00:00:00 2001 From: ztao Date: Fri, 9 Sep 2022 08:32:08 -0400 Subject: [PATCH] Sample the summary observed values --- core/include/prometheus/summary.h | 14 +++++++++++--- core/src/summary.cc | 23 ++++++++++++++++++----- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/core/include/prometheus/summary.h b/core/include/prometheus/summary.h index 7035459b..aa705beb 100644 --- a/core/include/prometheus/summary.h +++ b/core/include/prometheus/summary.h @@ -71,14 +71,21 @@ class PROMETHEUS_CPP_CORE_EXPORT Summary { /// and how smooth the time window is moved. With only one age bucket it /// effectively results in a complete reset of the summary each time max_age /// has passed. The default value is 5. + /// + /// \param sample_ratio Set the sample ratio for the observed values which are + /// used to calculate quantiles. When used in high throughput situations, if + /// not sampled the SDK will cause serious performance problem. The value + /// valid in [0, 1], and sample_ratio = 0 or 1 will not cause sample. The + /// default value is 0. explicit Summary(const Quantiles& quantiles, std::chrono::milliseconds max_age = std::chrono::seconds{60}, - int age_buckets = 5); + int age_buckets = 5, double sample_ratio = 0); - /// \copydoc Summary::Summary(const Quantiles&,std::chrono::milliseconds,int) + /// \copydoc Summary::Summary(const + /// Quantiles&,std::chrono::milliseconds,int,double) explicit Summary(Quantiles&& quantiles, std::chrono::milliseconds max_age = std::chrono::seconds{60}, - int age_buckets = 5); + int age_buckets = 5, double sample_ratio = 0); /// \brief Observe the given amount. void Observe(double value); @@ -94,6 +101,7 @@ class PROMETHEUS_CPP_CORE_EXPORT Summary { std::uint64_t count_{}; double sum_{}; detail::TimeWindowQuantiles quantile_values_; + int sample_ratio_threshold_{}; }; /// \brief Return a builder to configure and register a Summary metric. diff --git a/core/src/summary.cc b/core/src/summary.cc index 29902140..bb05e805 100644 --- a/core/src/summary.cc +++ b/core/src/summary.cc @@ -5,21 +5,34 @@ namespace prometheus { Summary::Summary(const Quantiles& quantiles, - const std::chrono::milliseconds max_age, const int age_buckets) + const std::chrono::milliseconds max_age, const int age_buckets, + const double sample_ratio) : quantiles_{quantiles}, - quantile_values_{quantiles_, max_age, age_buckets} {} + quantile_values_{quantiles_, max_age, age_buckets} { + if (sample_ratio > 0 && sample_ratio < 1) { + sample_ratio_threshold_ = sample_ratio * RAND_MAX; + } +} Summary::Summary(Quantiles&& quantiles, const std::chrono::milliseconds max_age, - const int age_buckets) + const int age_buckets, const double sample_ratio) : quantiles_{std::move(quantiles)}, - quantile_values_{quantiles_, max_age, age_buckets} {} + quantile_values_{quantiles_, max_age, age_buckets} { + if (sample_ratio > 0 && sample_ratio < 1) { + sample_ratio_threshold_ = sample_ratio * RAND_MAX; + } +} void Summary::Observe(const double value) { + bool should_observe = + (sample_ratio_threshold_ == 0 || sample_ratio_threshold_ < std::rand()); std::lock_guard lock(mutex_); count_ += 1; sum_ += value; - quantile_values_.insert(value); + if (should_observe) { + quantile_values_.insert(value); + } } ClientMetric Summary::Collect() const {