/proc/self/cwd/source/common/stats/histogram_impl.cc
Line | Count | Source (jump to first uncovered line) |
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 | 55.6k | computed_quantiles_(HistogramStatisticsImpl::supportedQuantiles().size(), 0.0), unit_(unit) { |
25 | 55.6k | refresh(histogram_ptr); |
26 | 55.6k | } |
27 | | |
28 | 222k | const std::vector<double>& HistogramStatisticsImpl::supportedQuantiles() const { |
29 | 222k | CONSTRUCT_ON_FIRST_USE(std::vector<double>, |
30 | 222k | {0, 0.25, 0.5, 0.75, 0.90, 0.95, 0.99, 0.995, 0.999, 1}); |
31 | 222k | } |
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 | 55.7k | 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 | 55.7k | constexpr double percent_scale = Histogram::PercentScale; |
72 | | |
73 | 55.7k | std::fill(computed_quantiles_.begin(), computed_quantiles_.end(), 0.0); |
74 | 55.7k | ASSERT(supportedQuantiles().size() == computed_quantiles_.size()); |
75 | 55.7k | hist_approx_quantile(new_histogram_ptr, supportedQuantiles().data(), supportedQuantiles().size(), |
76 | 55.7k | computed_quantiles_.data()); |
77 | 55.7k | if (unit_ == Histogram::Unit::Percent) { |
78 | 0 | for (double& val : computed_quantiles_) { |
79 | 0 | val /= percent_scale; |
80 | 0 | } |
81 | 0 | } |
82 | | |
83 | 55.7k | sample_count_ = hist_sample_count(new_histogram_ptr); |
84 | 55.7k | sample_sum_ = hist_approx_sum(new_histogram_ptr); |
85 | 55.7k | if (unit_ == Histogram::Unit::Percent) { |
86 | 0 | sample_sum_ /= percent_scale; |
87 | 0 | } |
88 | | |
89 | 55.7k | computed_buckets_.clear(); |
90 | 55.7k | ConstSupportedBuckets& supported_buckets = supportedBuckets(); |
91 | 55.7k | computed_buckets_.reserve(supported_buckets.size()); |
92 | 1.05M | for (auto bucket : supported_buckets) { |
93 | 1.05M | if (unit_ == Histogram::Unit::Percent) { |
94 | 0 | bucket *= percent_scale; |
95 | 0 | } |
96 | 1.05M | computed_buckets_.emplace_back(hist_approx_count_below(new_histogram_ptr, bucket)); |
97 | 1.05M | } |
98 | | |
99 | 55.7k | out_of_bound_count_ = hist_approx_count_above(new_histogram_ptr, supported_buckets.back()); |
100 | 55.7k | } |
101 | | |
102 | | HistogramSettingsImpl::HistogramSettingsImpl(const envoy::config::metrics::v3::StatsConfig& config, |
103 | | Server::Configuration::CommonFactoryContext& context) |
104 | 4.52k | : configs_([&config, &context]() { |
105 | 4.52k | std::vector<Config> configs; |
106 | 4.52k | for (const auto& matcher : config.histogram_bucket_settings()) { |
107 | 632 | std::vector<double> buckets{matcher.buckets().begin(), matcher.buckets().end()}; |
108 | 632 | std::sort(buckets.begin(), buckets.end()); |
109 | 632 | configs.emplace_back(Matchers::StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>( |
110 | 632 | matcher.match(), context), |
111 | 632 | std::move(buckets)); |
112 | 632 | } |
113 | | |
114 | 4.52k | return configs; |
115 | 4.52k | }()) {} |
116 | | |
117 | 28.0k | const ConstSupportedBuckets& HistogramSettingsImpl::buckets(absl::string_view stat_name) const { |
118 | 28.0k | for (const auto& config : configs_) { |
119 | 0 | if (config.first.match(stat_name)) { |
120 | 0 | return config.second; |
121 | 0 | } |
122 | 0 | } |
123 | 28.0k | return defaultBuckets(); |
124 | 28.0k | } |
125 | | |
126 | 28.0k | const ConstSupportedBuckets& HistogramSettingsImpl::defaultBuckets() { |
127 | 28.0k | CONSTRUCT_ON_FIRST_USE(ConstSupportedBuckets, |
128 | 28.0k | {0.5, 1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000, |
129 | 28.0k | 60000, 300000, 600000, 1800000, 3600000}); |
130 | 28.0k | } |
131 | | |
132 | | } // namespace Stats |
133 | | } // namespace Envoy |