LCOV - code coverage report
Current view: top level - source/common/stats - histogram_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 40 86 46.5 %
Date: 2024-01-05 06:35:25 Functions: 7 11 63.6 %

          Line data    Source code
       1             : #include "source/common/stats/histogram_impl.h"
       2             : 
       3             : #include <algorithm>
       4             : #include <string>
       5             : 
       6             : #include "source/common/common/utility.h"
       7             : 
       8             : #include "absl/strings/str_join.h"
       9             : 
      10             : namespace Envoy {
      11             : namespace Stats {
      12             : 
      13             : namespace {
      14             : const ConstSupportedBuckets default_buckets{};
      15             : }
      16             : 
      17             : HistogramStatisticsImpl::HistogramStatisticsImpl()
      18           0 :     : supported_buckets_(default_buckets), computed_quantiles_(supportedQuantiles().size(), 0.0) {}
      19             : 
      20             : HistogramStatisticsImpl::HistogramStatisticsImpl(const histogram_t* histogram_ptr,
      21             :                                                  Histogram::Unit unit,
      22             :                                                  ConstSupportedBuckets& supported_buckets)
      23             :     : supported_buckets_(supported_buckets),
      24        3086 :       computed_quantiles_(HistogramStatisticsImpl::supportedQuantiles().size(), 0.0), unit_(unit) {
      25        3086 :   refresh(histogram_ptr);
      26        3086 : }
      27             : 
      28        9258 : const std::vector<double>& HistogramStatisticsImpl::supportedQuantiles() const {
      29        9258 :   CONSTRUCT_ON_FIRST_USE(std::vector<double>,
      30        9258 :                          {0, 0.25, 0.5, 0.75, 0.90, 0.95, 0.99, 0.995, 0.999, 1});
      31        9258 : }
      32             : 
      33           0 : std::vector<uint64_t> HistogramStatisticsImpl::computeDisjointBuckets() const {
      34           0 :   std::vector<uint64_t> buckets;
      35           0 :   buckets.reserve(computed_buckets_.size());
      36           0 :   uint64_t previous_computed_bucket = 0;
      37           0 :   for (uint64_t computed_bucket : computed_buckets_) {
      38           0 :     buckets.push_back(computed_bucket - previous_computed_bucket);
      39           0 :     previous_computed_bucket = computed_bucket;
      40           0 :   }
      41           0 :   return buckets;
      42           0 : }
      43             : 
      44           0 : std::string HistogramStatisticsImpl::quantileSummary() const {
      45           0 :   std::vector<std::string> summary;
      46           0 :   const std::vector<double>& supported_quantiles = supportedQuantiles();
      47           0 :   summary.reserve(supported_quantiles.size());
      48           0 :   for (size_t i = 0; i < supported_quantiles.size(); ++i) {
      49           0 :     summary.push_back(
      50           0 :         fmt::format("P{:g}: {:g}", 100 * supported_quantiles[i], computed_quantiles_[i]));
      51           0 :   }
      52           0 :   return absl::StrJoin(summary, ", ");
      53           0 : }
      54             : 
      55           0 : std::string HistogramStatisticsImpl::bucketSummary() const {
      56           0 :   std::vector<std::string> bucket_summary;
      57           0 :   ConstSupportedBuckets& supported_buckets = supportedBuckets();
      58           0 :   bucket_summary.reserve(supported_buckets.size());
      59           0 :   for (size_t i = 0; i < supported_buckets.size(); ++i) {
      60           0 :     bucket_summary.push_back(fmt::format("B{:g}: {}", supported_buckets[i], computed_buckets_[i]));
      61           0 :   }
      62           0 :   return absl::StrJoin(bucket_summary, ", ");
      63           0 : }
      64             : 
      65             : /**
      66             :  * Clears the old computed values and refreshes it with values computed from passed histogram.
      67             :  */
      68        3086 : void HistogramStatisticsImpl::refresh(const histogram_t* new_histogram_ptr) {
      69             :   // Convert to double once to avoid needing to cast it on every use. Use a double
      70             :   // to ensure the compiler doesn't try to convert the expression to integer math.
      71        3086 :   constexpr double percent_scale = Histogram::PercentScale;
      72             : 
      73        3086 :   std::fill(computed_quantiles_.begin(), computed_quantiles_.end(), 0.0);
      74        3086 :   ASSERT(supportedQuantiles().size() == computed_quantiles_.size());
      75        3086 :   hist_approx_quantile(new_histogram_ptr, supportedQuantiles().data(), supportedQuantiles().size(),
      76        3086 :                        computed_quantiles_.data());
      77        3086 :   if (unit_ == Histogram::Unit::Percent) {
      78           0 :     for (double& val : computed_quantiles_) {
      79           0 :       val /= percent_scale;
      80           0 :     }
      81           0 :   }
      82             : 
      83        3086 :   sample_count_ = hist_sample_count(new_histogram_ptr);
      84        3086 :   sample_sum_ = hist_approx_sum(new_histogram_ptr);
      85        3086 :   if (unit_ == Histogram::Unit::Percent) {
      86           0 :     sample_sum_ /= percent_scale;
      87           0 :   }
      88             : 
      89        3086 :   computed_buckets_.clear();
      90        3086 :   ConstSupportedBuckets& supported_buckets = supportedBuckets();
      91        3086 :   computed_buckets_.reserve(supported_buckets.size());
      92       58634 :   for (auto bucket : supported_buckets) {
      93       58634 :     if (unit_ == Histogram::Unit::Percent) {
      94           0 :       bucket *= percent_scale;
      95           0 :     }
      96       58634 :     computed_buckets_.emplace_back(hist_approx_count_below(new_histogram_ptr, bucket));
      97       58634 :   }
      98             : 
      99        3086 :   out_of_bound_count_ = hist_approx_count_above(new_histogram_ptr, supported_buckets.back());
     100        3086 : }
     101             : 
     102             : HistogramSettingsImpl::HistogramSettingsImpl(const envoy::config::metrics::v3::StatsConfig& config)
     103         134 :     : configs_([&config]() {
     104         134 :         std::vector<Config> configs;
     105         134 :         for (const auto& matcher : config.histogram_bucket_settings()) {
     106           0 :           std::vector<double> buckets{matcher.buckets().begin(), matcher.buckets().end()};
     107           0 :           std::sort(buckets.begin(), buckets.end());
     108           0 :           configs.emplace_back(matcher.match(), std::move(buckets));
     109           0 :         }
     110             : 
     111         134 :         return configs;
     112         134 :       }()) {}
     113             : 
     114        1659 : const ConstSupportedBuckets& HistogramSettingsImpl::buckets(absl::string_view stat_name) const {
     115        1659 :   for (const auto& config : configs_) {
     116           0 :     if (config.first.match(stat_name)) {
     117           0 :       return config.second;
     118           0 :     }
     119           0 :   }
     120        1659 :   return defaultBuckets();
     121        1659 : }
     122             : 
     123        1659 : const ConstSupportedBuckets& HistogramSettingsImpl::defaultBuckets() {
     124        1659 :   CONSTRUCT_ON_FIRST_USE(ConstSupportedBuckets,
     125        1659 :                          {0.5, 1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000,
     126        1659 :                           60000, 300000, 600000, 1800000, 3600000});
     127        1659 : }
     128             : 
     129             : } // namespace Stats
     130             : } // namespace Envoy

Generated by: LCOV version 1.15