1
#pragma once
2

            
3
#include <cstdint>
4
#include <string>
5

            
6
#include "envoy/config/metrics/v3/stats.pb.h"
7
#include "envoy/stats/histogram.h"
8
#include "envoy/stats/stats.h"
9
#include "envoy/stats/store.h"
10

            
11
#include "source/common/common/matchers.h"
12
#include "source/common/common/non_copyable.h"
13
#include "source/common/stats/metric_impl.h"
14

            
15
#include "circllhist.h"
16

            
17
namespace Envoy {
18
namespace Stats {
19

            
20
class HistogramSettingsImpl : public HistogramSettings {
21
public:
22
10800
  HistogramSettingsImpl() = default;
23
  HistogramSettingsImpl(const envoy::config::metrics::v3::StatsConfig& config,
24
                        Server::Configuration::CommonFactoryContext& context);
25

            
26
  // HistogramSettings
27
  const ConstSupportedBuckets& buckets(absl::string_view stat_name) const override;
28
  absl::optional<uint32_t> bins(absl::string_view stat_name) const override;
29

            
30
  static ConstSupportedBuckets& defaultBuckets();
31

            
32
private:
33
  struct Config {
34
    Matchers::StringMatcherImpl matcher_;
35
    absl::optional<ConstSupportedBuckets> buckets_;
36
    absl::optional<uint32_t> bins_;
37
  };
38
  const std::vector<Config> configs_{};
39
};
40

            
41
/**
42
 * Implementation of HistogramStatistics for circllhist.
43
 */
44
class HistogramStatisticsImpl final : public HistogramStatistics, NonCopyable {
45
public:
46
  HistogramStatisticsImpl();
47

            
48
  /**
49
   * HistogramStatisticsImpl object is constructed using the passed in histogram.
50
   * @param histogram_ptr pointer to the histogram for which stats will be calculated. This pointer
51
   * will not be retained.
52
   */
53
  HistogramStatisticsImpl(
54
      const histogram_t* histogram_ptr, Histogram::Unit unit = Histogram::Unit::Unspecified,
55
      ConstSupportedBuckets& supported_buckets = HistogramSettingsImpl::defaultBuckets());
56

            
57
  void refresh(const histogram_t* new_histogram_ptr);
58

            
59
  // HistogramStatistics
60
  std::string quantileSummary() const override;
61
  std::string bucketSummary() const override;
62
  const std::vector<double>& supportedQuantiles() const final;
63
456
  const std::vector<double>& computedQuantiles() const override { return computed_quantiles_; }
64
411508
  ConstSupportedBuckets& supportedBuckets() const override { return supported_buckets_; }
65
649
  const std::vector<uint64_t>& computedBuckets() const override { return computed_buckets_; }
66
  std::vector<uint64_t> computeDisjointBuckets() const override;
67
32127
  uint64_t sampleCount() const override { return sample_count_; }
68
86
  uint64_t outOfBoundCount() const override { return out_of_bound_count_; }
69
347
  double sampleSum() const override { return sample_sum_; }
70

            
71
private:
72
  ConstSupportedBuckets& supported_buckets_;
73
  std::vector<double> computed_quantiles_;
74
  std::vector<uint64_t> computed_buckets_;
75
  uint64_t sample_count_{0};
76
  uint64_t out_of_bound_count_{0};
77
  double sample_sum_{0};
78
  const Histogram::Unit unit_{Histogram::Unit::Unspecified};
79
};
80

            
81
class HistogramImplHelper : public MetricImpl<Histogram> {
82
public:
83
  HistogramImplHelper(StatName name, StatName tag_extracted_name,
84
                      const StatNameTagVector& stat_name_tags, SymbolTable& symbol_table)
85
2684668
      : MetricImpl<Histogram>(name, tag_extracted_name, stat_name_tags, symbol_table) {}
86
1836581
  HistogramImplHelper(SymbolTable& symbol_table) : MetricImpl<Histogram>(symbol_table) {}
87

            
88
  // RefcountInterface
89
5464345
  void incRefCount() override { refcount_helper_.incRefCount(); }
90
5464345
  bool decRefCount() override { return refcount_helper_.decRefCount(); }
91
1
  uint32_t use_count() const override { return refcount_helper_.use_count(); }
92

            
93
private:
94
  RefcountHelper refcount_helper_;
95
};
96

            
97
/**
98
 * Histogram implementation for the heap.
99
 */
100
class HistogramImpl : public HistogramImplHelper {
101
public:
102
  HistogramImpl(StatName name, Unit unit, Store& parent, StatName tag_extracted_name,
103
                const StatNameTagVector& stat_name_tags)
104
2588745
      : HistogramImplHelper(name, tag_extracted_name, stat_name_tags, parent.symbolTable()),
105
2588745
        unit_(unit), parent_(parent) {}
106
2588745
  ~HistogramImpl() override {
107
    // We must explicitly free the StatName here in order to supply the
108
    // SymbolTable reference. An RAII alternative would be to store a
109
    // reference to the SymbolTable in MetricImpl, which would cost 8 bytes
110
    // per stat.
111
2588745
    MetricImpl::clear(symbolTable());
112
2588745
  }
113

            
114
  // Stats::Histogram
115
65297
  Unit unit() const override { return unit_; };
116
10887188
  void recordValue(uint64_t value) override { parent_.deliverHistogramToSinks(*this, value); }
117

            
118
18
  bool used() const override { return true; }
119
  void markUnused() override {}
120
42
  bool hidden() const override { return false; }
121
2590161
  SymbolTable& symbolTable() final { return parent_.symbolTable(); }
122

            
123
private:
124
  Unit unit_;
125

            
126
  // This is used for delivering the histogram data to sinks.
127
  Store& parent_;
128
};
129

            
130
/**
131
 * Null histogram implementation.
132
 * No-ops on all calls and requires no underlying metric or data.
133
 */
134
class NullHistogramImpl : public HistogramImplHelper {
135
public:
136
  explicit NullHistogramImpl(SymbolTable& symbol_table)
137
1836581
      : HistogramImplHelper(symbol_table), symbol_table_(symbol_table) {}
138
1836519
  ~NullHistogramImpl() override { MetricImpl::clear(symbol_table_); }
139

            
140
2
  bool used() const override { return false; }
141
  void markUnused() override {}
142
  bool hidden() const override { return false; }
143
27
  SymbolTable& symbolTable() override { return symbol_table_; }
144

            
145
22
  Unit unit() const override { return Unit::Null; };
146
10
  void recordValue(uint64_t) override {}
147

            
148
private:
149
  SymbolTable& symbol_table_;
150
};
151

            
152
} // namespace Stats
153
} // namespace Envoy