Line data Source code
1 : #pragma once
2 :
3 : #include <cstdint>
4 : #include <functional>
5 : #include <memory>
6 :
7 : #include "envoy/common/pure.h"
8 : #include "envoy/stats/histogram.h"
9 : #include "envoy/stats/tag.h"
10 :
11 : #include "absl/types/optional.h"
12 :
13 : namespace Envoy {
14 : namespace Stats {
15 :
16 : class Counter;
17 : class Gauge;
18 : class Histogram;
19 : class NullGaugeImpl;
20 : class Scope;
21 : class Store;
22 : class TextReadout;
23 :
24 : using CounterOptConstRef = absl::optional<std::reference_wrapper<const Counter>>;
25 : using GaugeOptConstRef = absl::optional<std::reference_wrapper<const Gauge>>;
26 : using HistogramOptConstRef = absl::optional<std::reference_wrapper<const Histogram>>;
27 : using TextReadoutOptConstRef = absl::optional<std::reference_wrapper<const TextReadout>>;
28 : using ConstScopeSharedPtr = std::shared_ptr<const Scope>;
29 : using ScopeSharedPtr = std::shared_ptr<Scope>;
30 :
31 : template <class StatType> using IterateFn = std::function<bool(const RefcountPtr<StatType>&)>;
32 :
33 : /**
34 : * A named scope for stats. Scopes are a grouping of stats that can be acted on
35 : * as a unit if needed (for example to free/delete all of them).
36 : *
37 : * Every counters, gauges, histograms, and text-readouts is managed by a Scope.
38 : *
39 : * Scopes are managed by shared pointers. This makes it possible for the admin
40 : * stats handler to safely capture all the scope references and remain robust to
41 : * other threads deleting those scopes while rendering an admin stats page.
42 : *
43 : * It is invalid to allocate a Scope using std::unique_ptr or directly on the
44 : * stack.
45 : *
46 : * We use std::shared_ptr rather than Stats::RefcountPtr, which we use for other
47 : * stats, because:
48 : * * existing uses of shared_ptr<Scope> exist in the Wasm extension and would
49 : * need to be rewritten to allow for RefcountPtr<Scope>.
50 : * * the main advantage of RefcountPtr is it's smaller per instance by 16
51 : * bytes, but there are not typically enough scopes that the extra per-scope
52 : * overhead would matter.
53 : * * It's a little less coding to use enable_shared_from_this compared to
54 : * adding a ref_count to the scope object, for each of its implementations.
55 : */
56 : class Scope : public std::enable_shared_from_this<Scope> {
57 : public:
58 26390 : virtual ~Scope() = default;
59 :
60 : /** @return a shared_ptr for this */
61 0 : ScopeSharedPtr getShared() { return shared_from_this(); }
62 :
63 : /** @return a const shared_ptr for this */
64 0 : ConstScopeSharedPtr getConstShared() const { return shared_from_this(); }
65 :
66 : /**
67 : * Allocate a new scope. NOTE: The implementation should correctly handle overlapping scopes
68 : * that point to the same reference counted backing stats. This allows a new scope to be
69 : * gracefully swapped in while an old scope with the same name is being destroyed.
70 : *
71 : * See also scopeFromStatName, which is preferred.
72 : *
73 : * @param name supplies the scope's namespace prefix.
74 : */
75 : virtual ScopeSharedPtr createScope(const std::string& name) PURE;
76 :
77 : /**
78 : * Allocate a new scope. NOTE: The implementation should correctly handle overlapping scopes
79 : * that point to the same reference counted backing stats. This allows a new scope to be
80 : * gracefully swapped in while an old scope with the same name is being destroyed.
81 : *
82 : * @param name supplies the scope's namespace prefix.
83 : */
84 : virtual ScopeSharedPtr scopeFromStatName(StatName name) PURE;
85 :
86 : /**
87 : * Creates a Counter from the stat name. Tag extraction will be performed on the name.
88 : * @param name The name of the stat, obtained from the SymbolTable.
89 : * @return a counter within the scope's namespace.
90 : */
91 91981 : Counter& counterFromStatName(const StatName& name) {
92 91981 : return counterFromStatNameWithTags(name, absl::nullopt);
93 91981 : }
94 : /**
95 : * Creates a Counter from the stat name and tags. If tags are not provided, tag extraction
96 : * will be performed on the name.
97 : * @param name The name of the stat, obtained from the SymbolTable.
98 : * @param tags optionally specified tags.
99 : * @return a counter within the scope's namespace.
100 : */
101 : virtual Counter& counterFromStatNameWithTags(const StatName& name,
102 : StatNameTagVectorOptConstRef tags) PURE;
103 :
104 : /**
105 : * TODO(#6667): this variant is deprecated: use counterFromStatName.
106 : * @param name The name, expressed as a string.
107 : * @return a counter within the scope's namespace.
108 : */
109 : virtual Counter& counterFromString(const std::string& name) PURE;
110 :
111 : /**
112 : * Creates a Gauge from the stat name. Tag extraction will be performed on the name.
113 : * @param name The name of the stat, obtained from the SymbolTable.
114 : * @param import_mode Whether hot-restart should accumulate this value.
115 : * @return a gauge within the scope's namespace.
116 : */
117 23730 : Gauge& gaugeFromStatName(const StatName& name, Gauge::ImportMode import_mode) {
118 23730 : return gaugeFromStatNameWithTags(name, absl::nullopt, import_mode);
119 23730 : }
120 :
121 : /**
122 : * Creates a Gauge from the stat name and tags. If tags are not provided, tag extraction
123 : * will be performed on the name.
124 : * @param name The name of the stat, obtained from the SymbolTable.
125 : * @param tags optionally specified tags.
126 : * @param import_mode Whether hot-restart should accumulate this value.
127 : * @return a gauge within the scope's namespace.
128 : */
129 : virtual Gauge& gaugeFromStatNameWithTags(const StatName& name, StatNameTagVectorOptConstRef tags,
130 : Gauge::ImportMode import_mode) PURE;
131 :
132 : /**
133 : * TODO(#6667): this variant is deprecated: use gaugeFromStatName.
134 : * @param name The name, expressed as a string.
135 : * @param import_mode Whether hot-restart should accumulate this value.
136 : * @return a gauge within the scope's namespace.
137 : */
138 : virtual Gauge& gaugeFromString(const std::string& name, Gauge::ImportMode import_mode) PURE;
139 :
140 : /**
141 : * Creates a Histogram from the stat name. Tag extraction will be performed on the name.
142 : * @param name The name of the stat, obtained from the SymbolTable.
143 : * @param unit The unit of measurement.
144 : * @return a histogram within the scope's namespace with a particular value type.
145 : */
146 2689 : Histogram& histogramFromStatName(const StatName& name, Histogram::Unit unit) {
147 2689 : return histogramFromStatNameWithTags(name, absl::nullopt, unit);
148 2689 : }
149 :
150 : /**
151 : * Creates a Histogram from the stat name and tags. If tags are not provided, tag extraction
152 : * will be performed on the name.
153 : * @param name The name of the stat, obtained from the SymbolTable.
154 : * @param tags optionally specified tags.
155 : * @param unit The unit of measurement.
156 : * @return a histogram within the scope's namespace with a particular value type.
157 : */
158 : virtual Histogram& histogramFromStatNameWithTags(const StatName& name,
159 : StatNameTagVectorOptConstRef tags,
160 : Histogram::Unit unit) PURE;
161 :
162 : /**
163 : * TODO(#6667): this variant is deprecated: use histogramFromStatName.
164 : * @param name The name, expressed as a string.
165 : * @param unit The unit of measurement.
166 : * @return a histogram within the scope's namespace with a particular value type.
167 : */
168 : virtual Histogram& histogramFromString(const std::string& name, Histogram::Unit unit) PURE;
169 :
170 : /**
171 : * Creates a TextReadout from the stat name. Tag extraction will be performed on the name.
172 : * @param name The name of the stat, obtained from the SymbolTable.
173 : * @return a text readout within the scope's namespace.
174 : */
175 234 : TextReadout& textReadoutFromStatName(const StatName& name) {
176 234 : return textReadoutFromStatNameWithTags(name, absl::nullopt);
177 234 : }
178 :
179 : /**
180 : * Creates a TextReadout from the stat name and tags. If tags are not provided, tag extraction
181 : * will be performed on the name.
182 : * @param name The name of the stat, obtained from the SymbolTable.
183 : * @param tags optionally specified tags.
184 : * @return a text readout within the scope's namespace.
185 : */
186 : virtual TextReadout& textReadoutFromStatNameWithTags(const StatName& name,
187 : StatNameTagVectorOptConstRef tags) PURE;
188 :
189 : /**
190 : * TODO(#6667): this variant is deprecated: use textReadoutFromStatName.
191 : * @param name The name, expressed as a string.
192 : * @return a text readout within the scope's namespace.
193 : */
194 : virtual TextReadout& textReadoutFromString(const std::string& name) PURE;
195 :
196 : /**
197 : * @param The name of the stat, obtained from the SymbolTable.
198 : * @return a reference to a counter within the scope's namespace, if it exists.
199 : */
200 : virtual CounterOptConstRef findCounter(StatName name) const PURE;
201 :
202 : /**
203 : * @param The name of the stat, obtained from the SymbolTable.
204 : * @return a reference to a gauge within the scope's namespace, if it exists.
205 : */
206 : virtual GaugeOptConstRef findGauge(StatName name) const PURE;
207 :
208 : /**
209 : * @param The name of the stat, obtained from the SymbolTable.
210 : * @return a reference to a histogram within the scope's namespace, if it
211 : * exists.
212 : */
213 : virtual HistogramOptConstRef findHistogram(StatName name) const PURE;
214 :
215 : /**
216 : * @param The name of the stat, obtained from the SymbolTable.
217 : * @return a reference to a text readout within the scope's namespace, if it exists.
218 : */
219 : virtual TextReadoutOptConstRef findTextReadout(StatName name) const PURE;
220 :
221 : /**
222 : * @return a reference to the symbol table.
223 : */
224 : virtual const SymbolTable& constSymbolTable() const PURE;
225 : virtual SymbolTable& symbolTable() PURE;
226 :
227 : /**
228 : * Calls 'fn' for every counter. Iteration stops if `fn` returns false;
229 : *
230 : * @param fn Function to be run for every counter, or until fn return false.
231 : * @return false if fn(counter) return false during iteration, true if every counter was hit.
232 : */
233 : virtual bool iterate(const IterateFn<Counter>& fn) const PURE;
234 :
235 : /**
236 : * Calls 'fn' for every gauge. Iteration stops if `fn` returns false;
237 : *
238 : * @param fn Function to be run for every gauge, or until fn return false.
239 : * @return false if fn(gauge) return false during iteration, true if every gauge was hit.
240 : */
241 : virtual bool iterate(const IterateFn<Gauge>& fn) const PURE;
242 :
243 : /**
244 : * Calls 'fn' for every histogram. Iteration stops if `fn` returns false;
245 : *
246 : * @param fn Function to be run for every histogram, or until fn return false.
247 : * @return false if fn(histogram) return false during iteration, true if every histogram was hit.
248 : */
249 : virtual bool iterate(const IterateFn<Histogram>& fn) const PURE;
250 :
251 : /**
252 : * Calls 'fn' for every text readout. Note that in the case of overlapping
253 : * scopes, the implementation may call fn more than one time for each
254 : * text readout. Iteration stops if `fn` returns false;
255 : *
256 : * @param fn Function to be run for every text readout, or until fn return false.
257 : * @return false if fn(text_readout) return false during iteration, true if every text readout
258 : * was hit.
259 : */
260 : virtual bool iterate(const IterateFn<TextReadout>& fn) const PURE;
261 :
262 : /**
263 : * @return the aggregated prefix for this scope. A trailing dot is not
264 : * included, even if one was supplied when creating the scope. If this is a
265 : * nested scope, it will include names from every level. E.g.
266 : * store.createScope("foo").createScope("bar").prefix() will be the StatName "foo.bar"
267 : */
268 : virtual StatName prefix() const PURE;
269 :
270 : /**
271 : * @return a reference to the Store object that owns this scope.
272 : */
273 : virtual Store& store() PURE;
274 : virtual const Store& constStore() const PURE;
275 : };
276 :
277 : } // namespace Stats
278 : } // namespace Envoy
|