Line data Source code
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 21460 : 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 : * @return a null counter that will ignore increments and always return 0. 122 : */ 123 : virtual Counter& nullCounter() PURE; 124 : 125 : /** 126 : * @return a null gauge that will ignore set() calls and always return 0. 127 : */ 128 : virtual Gauge& nullGauge() PURE; 129 : 130 : /** 131 : * Iterate over all stats that need to be flushed to sinks. Note, that implementations can 132 : * potentially hold on to a mutex that will deadlock if the passed in functors try to create 133 : * or delete a stat. 134 : * @param f_size functor that is provided the number of all stats that will be flushed to sinks. 135 : * Note that this is called only once, prior to any calls to f_stat. 136 : * @param f_stat functor that is provided one stat that will be flushed to sinks, at a time. 137 : */ 138 : virtual void forEachSinkedCounter(SizeFn f_size, StatFn<Counter> f_stat) const PURE; 139 : virtual void forEachSinkedGauge(SizeFn f_size, StatFn<Gauge> f_stat) const PURE; 140 : virtual void forEachSinkedTextReadout(SizeFn f_size, StatFn<TextReadout> f_stat) const PURE; 141 : virtual void forEachSinkedHistogram(SizeFn f_size, StatFn<ParentHistogram> f_stat) const PURE; 142 : 143 : /** 144 : * Calls 'fn' for every stat. Note that in the case of overlapping scopes, the 145 : * implementation may call fn more than one time for each counter. Iteration 146 : * stops if `fn` returns false; 147 : * 148 : * @param fn Function to be run for every counter, or until fn return false. 149 : * @return false if fn(counter) return false during iteration, true if every counter was hit. 150 : */ 151 : virtual bool iterate(const IterateFn<Counter>& fn) const PURE; 152 : virtual bool iterate(const IterateFn<Gauge>& fn) const PURE; 153 : virtual bool iterate(const IterateFn<Histogram>& fn) const PURE; 154 : virtual bool iterate(const IterateFn<TextReadout>& fn) const PURE; 155 : 156 : // Delegate some methods to the root scope; these are exposed to make it more 157 : // convenient to use stats_macros.h. We may consider dropping them if desired, 158 : // when we resolve #24007 or in the next follow-up. 159 12175 : Counter& counterFromString(const std::string& name) { 160 12175 : return rootScope()->counterFromString(name); 161 12175 : } 162 7369 : Gauge& gaugeFromString(const std::string& name, Gauge::ImportMode import_mode) { 163 7369 : return rootScope()->gaugeFromString(name, import_mode); 164 7369 : } 165 0 : TextReadout& textReadoutFromString(const std::string& name) { 166 0 : return rootScope()->textReadoutFromString(name); 167 0 : } 168 134 : Histogram& histogramFromString(const std::string& name, Histogram::Unit unit) { 169 134 : return rootScope()->histogramFromString(name, unit); 170 134 : } 171 : 172 : /** 173 : * @return a scope of the given name. 174 : */ 175 4714 : ScopeSharedPtr createScope(const std::string& name) { return rootScope()->createScope(name); } 176 : 177 : /** 178 : * Extracts tags from the name and appends them to the provided StatNameTagVector. 179 : * The StatName for the extracted tags will be saved in the provided pool. 180 : * @param name The stat name. 181 : * @param pool The pool to create the tags in. 182 : * @param stat_tags The stat name tags vector to append the tags to. 183 : */ 184 : virtual void extractAndAppendTags(StatName name, StatNamePool& pool, 185 : StatNameTagVector& stat_tags) PURE; 186 : 187 : /** 188 : * Extracts tags from the name and appends them to the provided StatNameTagVector. 189 : * The StatName for the extracted tags will be saved in the provided pool. 190 : * @param name The stat name. 191 : * @param pool The pool to create the tags in. 192 : * @param stat_tags The stat name tags vector to append the tags to. 193 : */ 194 : virtual void extractAndAppendTags(absl::string_view name, StatNamePool& pool, 195 : StatNameTagVector& stat_tags) PURE; 196 : 197 : /** 198 : * Returns the configured fixed tags (which don't depend on the name of the stat). 199 : */ 200 : virtual const TagVector& fixedTags() PURE; 201 : }; 202 : 203 : using StorePtr = std::unique_ptr<Store>; 204 : 205 : /** 206 : * Callback invoked when a store's mergeHistogram() runs. 207 : */ 208 : using PostMergeCb = std::function<void()>; 209 : 210 : /** 211 : * The root of the stat store. 212 : */ 213 : class StoreRoot : public Store { 214 : public: 215 : /** 216 : * Add a sink that is used for stat flushing. 217 : */ 218 : virtual void addSink(Sink& sink) PURE; 219 : 220 : /** 221 : * Set the given tag producer to control tags. 222 : */ 223 : virtual void setTagProducer(TagProducerPtr&& tag_producer) PURE; 224 : 225 : /** 226 : * Attach a StatsMatcher to this StoreRoot to prevent the initialization of stats according to 227 : * some ruleset. 228 : * @param stats_matcher a StatsMatcher to attach to this StoreRoot. 229 : */ 230 : virtual void setStatsMatcher(StatsMatcherPtr&& stats_matcher) PURE; 231 : 232 : /** 233 : * Attach a HistogramSettings to this StoreRoot to generate histogram configurations 234 : * according to some ruleset. 235 : */ 236 : virtual void setHistogramSettings(HistogramSettingsConstPtr&& histogram_settings) PURE; 237 : 238 : /** 239 : * Initialize the store for threading. This will be called once after all worker threads have 240 : * been initialized. At this point the store can initialize itself for multi-threaded operation. 241 : */ 242 : virtual void initializeThreading(Event::Dispatcher& main_thread_dispatcher, 243 : ThreadLocal::Instance& tls) PURE; 244 : 245 : /** 246 : * Shutdown threading support in the store. This is called once when the server is about to shut 247 : * down. 248 : */ 249 : virtual void shutdownThreading() PURE; 250 : 251 : /** 252 : * Called during the flush process to merge all the thread local histograms. The passed in 253 : * callback will be called on the main thread, but it will happen after the method returns 254 : * which means that the actual flush process will happen on the main thread after this method 255 : * returns. It is expected that only one merge runs at any time and concurrent calls to this 256 : * method would be asserted. 257 : */ 258 : virtual void mergeHistograms(PostMergeCb merge_complete_cb) PURE; 259 : 260 : /** 261 : * Set predicates for filtering stats to be flushed to sinks. 262 : * Note that if the sink predicates object is set, we do not send non-sink stats over to the 263 : * child process during hot restart. This will result in the admin stats console being wrong 264 : * during hot restart. 265 : */ 266 : virtual void setSinkPredicates(std::unique_ptr<SinkPredicates>&& sink_predicates) PURE; 267 : 268 : virtual OptRef<SinkPredicates> sinkPredicates() PURE; 269 : }; 270 : 271 : using StoreRootPtr = std::unique_ptr<StoreRoot>; 272 : 273 : } // namespace Stats 274 : } // namespace Envoy