Line data Source code
1 : #pragma once 2 : 3 : #include <vector> 4 : 5 : #include "envoy/common/optref.h" 6 : #include "envoy/stats/allocator.h" 7 : #include "envoy/stats/sink.h" 8 : #include "envoy/stats/stats.h" 9 : 10 : #include "source/common/common/thread_synchronizer.h" 11 : #include "source/common/stats/metric_impl.h" 12 : 13 : #include "absl/container/flat_hash_set.h" 14 : #include "absl/strings/string_view.h" 15 : 16 : namespace Envoy { 17 : namespace Stats { 18 : 19 : class AllocatorImpl : public Allocator { 20 : public: 21 : static const char DecrementToZeroSyncPoint[]; 22 : 23 21460 : AllocatorImpl(SymbolTable& symbol_table) : symbol_table_(symbol_table) {} 24 : ~AllocatorImpl() override; 25 : 26 : // Allocator 27 : CounterSharedPtr makeCounter(StatName name, StatName tag_extracted_name, 28 : const StatNameTagVector& stat_name_tags) override; 29 : GaugeSharedPtr makeGauge(StatName name, StatName tag_extracted_name, 30 : const StatNameTagVector& stat_name_tags, 31 : Gauge::ImportMode import_mode) override; 32 : TextReadoutSharedPtr makeTextReadout(StatName name, StatName tag_extracted_name, 33 : const StatNameTagVector& stat_name_tags) override; 34 3031553 : SymbolTable& symbolTable() override { return symbol_table_; } 35 0 : const SymbolTable& constSymbolTable() const override { return symbol_table_; } 36 : 37 : void forEachCounter(SizeFn, StatFn<Counter>) const override; 38 : 39 : void forEachGauge(SizeFn, StatFn<Gauge>) const override; 40 : 41 : void forEachTextReadout(SizeFn, StatFn<TextReadout>) const override; 42 : 43 : void forEachSinkedCounter(SizeFn f_size, StatFn<Counter> f_stat) const override; 44 : void forEachSinkedGauge(SizeFn f_size, StatFn<Gauge> f_stat) const override; 45 : void forEachSinkedTextReadout(SizeFn f_size, StatFn<TextReadout> f_stat) const override; 46 : 47 : void setSinkPredicates(std::unique_ptr<SinkPredicates>&& sink_predicates) override; 48 : #ifndef ENVOY_CONFIG_COVERAGE 49 : void debugPrint(); 50 : #endif 51 : 52 : /** 53 : * @return a thread synchronizer object used for reproducing a race-condition in tests. 54 : */ 55 327633 : Thread::ThreadSynchronizer& sync() { return sync_; } 56 : 57 : /** 58 : * @return whether the allocator's mutex is locked, exposed for testing purposes. 59 : */ 60 : bool isMutexLockedForTest(); 61 : 62 : void markCounterForDeletion(const CounterSharedPtr& counter) override; 63 : void markGaugeForDeletion(const GaugeSharedPtr& gauge) override; 64 : void markTextReadoutForDeletion(const TextReadoutSharedPtr& text_readout) override; 65 : 66 : protected: 67 : virtual Counter* makeCounterInternal(StatName name, StatName tag_extracted_name, 68 : const StatNameTagVector& stat_name_tags); 69 : 70 : private: 71 : template <class BaseClass> friend class StatsSharedImpl; 72 : friend class CounterImpl; 73 : friend class GaugeImpl; 74 : friend class TextReadoutImpl; 75 : friend class NotifyingAllocatorImpl; 76 : 77 : // A mutex is needed here to protect both the stats_ object from both 78 : // alloc() and free() operations. Although alloc() operations are called under existing locking, 79 : // free() operations are made from the destructors of the individual stat objects, which are not 80 : // protected by locks. 81 : mutable Thread::MutexBasicLockable mutex_; 82 : 83 : StatSet<Counter> counters_ ABSL_GUARDED_BY(mutex_); 84 : StatSet<Gauge> gauges_ ABSL_GUARDED_BY(mutex_); 85 : StatSet<TextReadout> text_readouts_ ABSL_GUARDED_BY(mutex_); 86 : 87 : template <typename StatType> using StatPointerSet = absl::flat_hash_set<StatType*>; 88 : // Stat pointers that participate in the flush to sink process. 89 : StatPointerSet<Counter> sinked_counters_ ABSL_GUARDED_BY(mutex_); 90 : StatPointerSet<Gauge> sinked_gauges_ ABSL_GUARDED_BY(mutex_); 91 : StatPointerSet<TextReadout> sinked_text_readouts_ ABSL_GUARDED_BY(mutex_); 92 : 93 : // Predicates used to filter stats to be flushed. 94 : std::unique_ptr<SinkPredicates> sink_predicates_; 95 : SymbolTable& symbol_table_; 96 : 97 : Thread::ThreadSynchronizer sync_; 98 : 99 : // Retain storage for deleted stats; these are no longer in maps because 100 : // the matcher-pattern was established after they were created. Since the 101 : // stats are held by reference in code that expects them to be there, we 102 : // can't actually delete the stats. 103 : // 104 : // It seems like it would be better to have each client that expects a stat 105 : // to exist to hold it as (e.g.) a CounterSharedPtr rather than a Counter& 106 : // but that would be fairly complex to change. 107 : std::vector<CounterSharedPtr> deleted_counters_ ABSL_GUARDED_BY(mutex_); 108 : std::vector<GaugeSharedPtr> deleted_gauges_ ABSL_GUARDED_BY(mutex_); 109 : std::vector<TextReadoutSharedPtr> deleted_text_readouts_ ABSL_GUARDED_BY(mutex_); 110 : }; 111 : 112 : } // namespace Stats 113 : } // namespace Envoy