1
#pragma once
2

            
3
#include <cstdint>
4
#include <memory>
5
#include <vector>
6

            
7
#include "envoy/common/pure.h"
8
#include "envoy/stats/refcount_ptr.h"
9
#include "envoy/stats/stats.h"
10

            
11
namespace Envoy {
12
namespace Stats {
13

            
14
using ConstSupportedBuckets = const std::vector<double>;
15

            
16
class HistogramSettings {
17
public:
18
21479
  virtual ~HistogramSettings() = default;
19

            
20
  /**
21
   * For formats like Prometheus where the entire histogram is published (but not
22
   * like statsd where each value to include in the histogram is emitted separately),
23
   * get the limits for each histogram bucket.
24
   * @return The buckets for the histogram. Each value is an upper bound of a bucket.
25
   */
26
  virtual ConstSupportedBuckets& buckets(absl::string_view stat_name) const PURE;
27

            
28
  /**
29
   * Number of bins to pre-allocate per each thread instance (times 2 for active/passive
30
   * version of the histogram).
31
   * @return An optional override for the number of bins.
32
   */
33
  virtual absl::optional<uint32_t> bins(absl::string_view stat_name) const PURE;
34
};
35

            
36
using HistogramSettingsConstPtr = std::unique_ptr<const HistogramSettings>;
37

            
38
/**
39
 * Holds the computed statistics for a histogram.
40
 */
41
class HistogramStatistics {
42
public:
43
395119
  virtual ~HistogramStatistics() = default;
44

            
45
  /**
46
   * Returns quantile summary representation of the histogram.
47
   */
48
  virtual std::string quantileSummary() const PURE;
49

            
50
  /**
51
   * Returns bucket summary representation of the histogram.
52
   */
53
  virtual std::string bucketSummary() const PURE;
54

            
55
  /**
56
   * Returns supported quantiles.
57
   */
58
  virtual const std::vector<double>& supportedQuantiles() const PURE;
59

            
60
  /**
61
   * Returns computed quantile values during the period.
62
   */
63
  virtual const std::vector<double>& computedQuantiles() const PURE;
64

            
65
  /**
66
   * Returns supported buckets. Each value is the upper bound of the bucket
67
   * with 0 as the implicit lower bound. For timers, these bucket thresholds
68
   * are in milliseconds but the thresholds are applicable to all types of data.
69
   */
70
  virtual ConstSupportedBuckets& supportedBuckets() const PURE;
71

            
72
  /**
73
   * Returns computed bucket values during the period. The vector contains an approximation
74
   * of samples below each quantile bucket defined in supportedBuckets(). This vector is
75
   * guaranteed to be the same length as supportedBuckets().
76
   */
77
  virtual const std::vector<uint64_t>& computedBuckets() const PURE;
78

            
79
  /**
80
   * Returns version of computedBuckets() with disjoint buckets. This vector is
81
   * guaranteed to be the same length as supportedBuckets().
82
   */
83
  virtual std::vector<uint64_t> computeDisjointBuckets() const PURE;
84

            
85
  /**
86
   * Returns number of values during the period. This number may be an approximation
87
   * of the number of samples in the histogram, it is not guaranteed that this will be
88
   * 100% the number of samples observed.
89
   */
90
  virtual uint64_t sampleCount() const PURE;
91

            
92
  /**
93
   * Returns sum of all values during the period.
94
   */
95
  virtual double sampleSum() const PURE;
96

            
97
  /**
98
   * Returns the count of values which are out of the boundaries of the histogram bins.
99
   * I.e., the count of values in the (bound_of_last_bucket, +inf) bucket.
100
   */
101
  virtual uint64_t outOfBoundCount() const PURE;
102
};
103

            
104
/**
105
 * A histogram that records values one at a time.
106
 * Note: Histograms now incorporate what used to be timers because the only
107
 * difference between the two stat types was the units being represented.
108
 */
109
class Histogram : public Metric {
110
public:
111
  /**
112
   * Histogram values represent scalar quantity like time, length, mass,
113
   * distance, or in general anything which has only magnitude and no other
114
   * characteristics. These are often accompanied by a unit of measurement.
115
   * This enum defines units for commonly measured quantities. Base units
116
   * are preferred unless they are not granular enough to be useful as an
117
   * integer.
118
   */
119
  enum class Unit {
120
    Null,        // The histogram has been rejected, i.e. it's a null histogram and is not recording
121
                 // anything.
122
    Unspecified, // Measured quantity does not require a unit, e.g. "items".
123
    Bytes,
124
    Microseconds,
125
    Milliseconds,
126
    Percent, // A percent value stored as fixed-point, where the stored value is divided by
127
             // PercentScale to get the actual value, eg a value of 100% (or 1.0) is encoded as
128
             // PercentScale, 50% is encoded as PercentScale * 0.5. Encoding as fixed-point allows
129
             // enough dynamic range, without needing to support floating-point values in
130
             // histograms.
131
  };
132

            
133
  // The scaling factor for Unit::Percent.
134
  static constexpr uint64_t PercentScale = 1000000;
135

            
136
4718869
  ~Histogram() override = default;
137

            
138
  /**
139
   * @return the unit of measurement for values recorded by the histogram.
140
   */
141
  virtual Unit unit() const PURE;
142

            
143
  /**
144
   * Records an unsigned value in the unit specified during the construction.
145
   */
146
  virtual void recordValue(uint64_t value) PURE;
147
};
148

            
149
using HistogramSharedPtr = RefcountPtr<Histogram>;
150

            
151
/**
152
 * A histogram that is stored in main thread and provides summary view of the histogram.
153
 */
154
class ParentHistogram : public Histogram {
155
public:
156
197532
  ~ParentHistogram() override = default;
157

            
158
  /**
159
   * This method is called during the main stats flush process for each of the histograms and used
160
   * to merge the histogram values.
161
   */
162
  virtual void merge() PURE;
163

            
164
  /**
165
   * Returns the interval histogram summary statistics for the flush interval.
166
   */
167
  virtual const HistogramStatistics& intervalStatistics() const PURE;
168

            
169
  /**
170
   * Returns the cumulative histogram summary statistics.
171
   */
172
  virtual const HistogramStatistics& cumulativeStatistics() const PURE;
173

            
174
  /**
175
   * Returns the quantile summary representation.
176
   */
177
  virtual std::string quantileSummary() const PURE;
178

            
179
  /**
180
   * Returns the bucket summary representation.
181
   */
182
  virtual std::string bucketSummary() const PURE;
183

            
184
  // Holds detailed value and counts for a histogram bucket.
185
  struct Bucket {
186
    double lower_bound_{0}; // Bound of bucket that's closest to zero.
187
    double width_{0};
188
    uint64_t count_{0};
189
  };
190

            
191
  /**
192
   * @return a vector of histogram buckets collected since binary start or reset.
193
   */
194
  virtual std::vector<Bucket> detailedTotalBuckets() const PURE;
195

            
196
  /**
197
   * @return bucket data collected since the most recent stat sink. Note that
198
   *         the number of interval buckets is likely to be much smaller than
199
   *         the number of detailed buckets.
200
   */
201
  virtual std::vector<Bucket> detailedIntervalBuckets() const PURE;
202

            
203
  /**
204
   * Returns the approximate cumulative count of samples less than or equal to the given value
205
   * in the cumulative histogram.
206
   */
207
  virtual uint64_t cumulativeCountLessThanOrEqualToValue(double value) const PURE;
208
};
209

            
210
using ParentHistogramSharedPtr = RefcountPtr<ParentHistogram>;
211

            
212
} // namespace Stats
213
} // namespace Envoy