1
#pragma once
2

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

            
7
#include "envoy/common/optref.h"
8
#include "envoy/common/pure.h"
9
#include "envoy/stats/histogram.h"
10
#include "envoy/stats/scope.h"
11
#include "envoy/stats/stats.h"
12
#include "envoy/stats/stats_matcher.h"
13
#include "envoy/stats/tag_producer.h"
14

            
15
namespace Envoy {
16
namespace Event {
17

            
18
class Dispatcher;
19
}
20

            
21
namespace ThreadLocal {
22
class Instance;
23
}
24

            
25
namespace Stats {
26

            
27
class Sink;
28
class SinkPredicates;
29
class StatNamePool;
30

            
31
/**
32
 * Store keeps track of all Scopes created in it, and the Scopes manage
33
 * individual stats. Each stat is defined in a scope. There is a single root
34
 * scope created in the Store, and more sub-scopes can be created. Scopes do not
35
 * own the scopes created underneath; they are managed by the return
36
 * SharePtr. However, sub-scopes combine the prefixes from their parental chain.
37
 *
38
 * Stores enable iteration over all stats in its transitively owned Scopes,
39
 *
40
 * There is typically one Store instance in a test or binary, though Isolated
41
 * Stores can be created in some scenarios. Stores are typically allocated
42
 * as part of other objects or via std::unique_ptr.
43
 *
44
 * In contrast, Scopes are managed via shared_ptr, unique nickname
45
 * ScopeSharedPtr, and should not be directly instantiated or allocated via
46
 * std::unique_ptr.
47
 *
48
 * A reference to the root-scope held by the Store until it shuts down. Holding
49
 * onto a reference to the root-scope's shared_ptr that outlives the Store is
50
 * not allowed.
51
 */
52
class Store {
53
public:
54
1836927
  virtual ~Store() = default;
55

            
56
  /**
57
   * @return the root scope (creating it if necessary)
58
   */
59
  virtual ScopeSharedPtr rootScope() PURE;
60

            
61
  /**
62
   * @return the root scope (creating it if necessary)
63
   */
64
  virtual ConstScopeSharedPtr constRootScope() const PURE;
65

            
66
  /**
67
   * @return The symbol table.
68
   **/
69
  virtual const SymbolTable& constSymbolTable() const PURE;
70

            
71
  /**
72
   * @return The symbol table.
73
   **/
74
  virtual SymbolTable& symbolTable() PURE;
75

            
76
  /**
77
   * Deliver an individual histogram value to all registered sinks.
78
   */
79
  virtual void deliverHistogramToSinks(const Histogram& histogram, uint64_t value) PURE;
80

            
81
  /**
82
   * @return a list of all known counters.
83
   */
84
  virtual std::vector<CounterSharedPtr> counters() const PURE;
85

            
86
  /**
87
   * @return a list of all known gauges.
88
   */
89
  virtual std::vector<GaugeSharedPtr> gauges() const PURE;
90

            
91
  /**
92
   * @return a list of all known text readouts.
93
   */
94
  virtual std::vector<TextReadoutSharedPtr> textReadouts() const PURE;
95

            
96
  /**
97
   * @return a list of all known histograms.
98
   */
99
  virtual std::vector<ParentHistogramSharedPtr> histograms() const PURE;
100

            
101
  /**
102
   * Iterate over all stats. Note, that implementations can potentially hold on
103
   * to a mutex that will deadlock if the passed in functors try to create or
104
   * delete a stat. Also note that holding onto the stat or scope reference
105
   * after forEach* is not supported, as scope/stat deletions can occur in any
106
   * thread. Implementation locks ensures the stat/scope is valid until the
107
   * f_stat returns.
108
   *
109
   * @param f_size functor that is provided the current number of all
110
   * stats. Note that this is called only once, prior to any calls to f_stat.
111
   * @param f_stat functor that is provided one stat at a time from the stats
112
   * container.
113
   */
114
  virtual void forEachCounter(SizeFn f_size, StatFn<Counter> f_stat) const PURE;
115
  virtual void forEachGauge(SizeFn f_size, StatFn<Gauge> f_stat) const PURE;
116
  virtual void forEachTextReadout(SizeFn f_size, StatFn<TextReadout> f_stat) const PURE;
117
  virtual void forEachHistogram(SizeFn f_size, StatFn<ParentHistogram> f_stat) const PURE;
118
  virtual void forEachScope(SizeFn f_size, StatFn<const Scope> f_stat) const PURE;
119

            
120
  /**
121
   * Delete unused metrics from all the evictable scope caches, and mark the rest as unused.
122
   */
123
  virtual void evictUnused() PURE;
124

            
125
  /**
126
   * @return a null counter that will ignore increments and always return 0.
127
   */
128
  virtual Counter& nullCounter() PURE;
129

            
130
  /**
131
   * @return a null gauge that will ignore set() calls and always return 0.
132
   */
133
  virtual Gauge& nullGauge() PURE;
134

            
135
  /**
136
   * Iterate over all stats that need to be flushed to sinks. Note, that implementations can
137
   * potentially hold on to a mutex that will deadlock if the passed in functors try to create
138
   * or delete a stat.
139
   * @param f_size functor that is provided the number of all stats that will be flushed to sinks.
140
   * Note that this is called only once, prior to any calls to f_stat.
141
   * @param f_stat functor that is provided one stat that will be flushed to sinks, at a time.
142
   */
143
  virtual void forEachSinkedCounter(SizeFn f_size, StatFn<Counter> f_stat) const PURE;
144
  virtual void forEachSinkedGauge(SizeFn f_size, StatFn<Gauge> f_stat) const PURE;
145
  virtual void forEachSinkedTextReadout(SizeFn f_size, StatFn<TextReadout> f_stat) const PURE;
146
  virtual void forEachSinkedHistogram(SizeFn f_size, StatFn<ParentHistogram> f_stat) const PURE;
147

            
148
  /**
149
   * Calls 'fn' for every stat. Note that in the case of overlapping scopes, the
150
   * implementation may call fn more than one time for each counter. Iteration
151
   * stops if `fn` returns false;
152
   *
153
   * @param fn Function to be run for every counter, or until fn return false.
154
   * @return false if fn(counter) return false during iteration, true if every counter was hit.
155
   */
156
  virtual bool iterate(const IterateFn<Counter>& fn) const PURE;
157
  virtual bool iterate(const IterateFn<Gauge>& fn) const PURE;
158
  virtual bool iterate(const IterateFn<Histogram>& fn) const PURE;
159
  virtual bool iterate(const IterateFn<TextReadout>& fn) const PURE;
160

            
161
  // Delegate some methods to the root scope; these are exposed to make it more
162
  // convenient to use stats_macros.h. We may consider dropping them if desired,
163
  // when we resolve #24007 or in the next follow-up.
164
434092
  Counter& counterFromString(const std::string& name) {
165
434092
    return rootScope()->counterFromString(name);
166
434092
  }
167
227840
  Gauge& gaugeFromString(const std::string& name, Gauge::ImportMode import_mode) {
168
227840
    return rootScope()->gaugeFromString(name, import_mode);
169
227840
  }
170
7
  TextReadout& textReadoutFromString(const std::string& name) {
171
7
    return rootScope()->textReadoutFromString(name);
172
7
  }
173
10714
  Histogram& histogramFromString(const std::string& name, Histogram::Unit unit) {
174
10714
    return rootScope()->histogramFromString(name, unit);
175
10714
  }
176

            
177
  /**
178
   * @return a scope of the given name.
179
   */
180
  ScopeSharedPtr createScope(const std::string& name, bool evictable = false,
181
                             const ScopeStatsLimitSettings& limits = {},
182
445902
                             StatsMatcherSharedPtr matcher = nullptr) {
183
445902
    return rootScope()->createScope(name, evictable, limits, std::move(matcher));
184
445902
  }
185

            
186
  /**
187
   * Extracts tags from the name and appends them to the provided StatNameTagVector.
188
   *     The StatName for the extracted tags will be saved in the provided pool.
189
   * @param name The stat name.
190
   * @param pool The pool to create the tags in.
191
   * @param stat_tags The stat name tags vector to append the tags to.
192
   */
193
  virtual void extractAndAppendTags(StatName name, StatNamePool& pool,
194
                                    StatNameTagVector& stat_tags) PURE;
195

            
196
  /**
197
   * Extracts tags from the name and appends them to the provided StatNameTagVector.
198
   *     The StatName for the extracted tags will be saved in the provided pool.
199
   * @param name The stat name.
200
   * @param pool The pool to create the tags in.
201
   * @param stat_tags The stat name tags vector to append the tags to.
202
   */
203
  virtual void extractAndAppendTags(absl::string_view name, StatNamePool& pool,
204
                                    StatNameTagVector& stat_tags) PURE;
205

            
206
  /**
207
   * Returns the configured fixed tags (which don't depend on the name of the stat).
208
   */
209
  virtual const TagVector& fixedTags() PURE;
210
};
211

            
212
using StorePtr = std::unique_ptr<Store>;
213

            
214
/**
215
 * Callback invoked when a store's mergeHistogram() runs.
216
 */
217
using PostMergeCb = std::function<void()>;
218

            
219
/**
220
 * The root of the stat store.
221
 */
222
class StoreRoot : public Store {
223
public:
224
  /**
225
   * Add a sink that is used for stat flushing.
226
   */
227
  virtual void addSink(Sink& sink) PURE;
228

            
229
  /**
230
   * Set the given tag producer to control tags.
231
   */
232
  virtual void setTagProducer(TagProducerPtr&& tag_producer) PURE;
233

            
234
  /**
235
   * Attach a StatsMatcher to this StoreRoot to prevent the initialization of stats according to
236
   * some ruleset.
237
   * @param stats_matcher a StatsMatcher to attach to this StoreRoot.
238
   */
239
  virtual void setStatsMatcher(StatsMatcherPtr&& stats_matcher) PURE;
240

            
241
  /**
242
   * Attach a HistogramSettings to this StoreRoot to generate histogram configurations
243
   * according to some ruleset.
244
   */
245
  virtual void setHistogramSettings(HistogramSettingsConstPtr&& histogram_settings) PURE;
246

            
247
  /**
248
   * Initialize the store for threading. This will be called once after all worker threads have
249
   * been initialized. At this point the store can initialize itself for multi-threaded operation.
250
   */
251
  virtual void initializeThreading(Event::Dispatcher& main_thread_dispatcher,
252
                                   ThreadLocal::Instance& tls) PURE;
253

            
254
  /**
255
   * Shutdown threading support in the store. This is called once when the server is about to shut
256
   * down.
257
   */
258
  virtual void shutdownThreading() PURE;
259

            
260
  /**
261
   * Called during the flush process to merge all the thread local histograms. The passed in
262
   * callback will be called on the main thread, but it will happen after the method returns
263
   * which means that the actual flush process will happen on the main thread after this method
264
   * returns. It is expected that only one merge runs at any time and concurrent calls to this
265
   * method would be asserted.
266
   */
267
  virtual void mergeHistograms(PostMergeCb merge_complete_cb) PURE;
268

            
269
  /**
270
   * Set predicates for filtering stats to be flushed to sinks.
271
   * Note that if the sink predicates object is set, we do not send non-sink stats over to the
272
   * child process during hot restart. This will result in the admin stats console being wrong
273
   * during hot restart.
274
   */
275
  virtual void setSinkPredicates(std::unique_ptr<SinkPredicates>&& sink_predicates) PURE;
276

            
277
  virtual OptRef<SinkPredicates> sinkPredicates() PURE;
278
};
279

            
280
using StoreRootPtr = std::unique_ptr<StoreRoot>;
281

            
282
} // namespace Stats
283
} // namespace Envoy