Line data Source code
1 : #pragma once 2 : 3 : #include <cstdint> 4 : #include <memory> 5 : #include <string> 6 : #include <vector> 7 : 8 : #include "envoy/common/pure.h" 9 : #include "envoy/stats/refcount_ptr.h" 10 : #include "envoy/stats/tag.h" 11 : 12 : #include "absl/strings/string_view.h" 13 : 14 : namespace Envoy { 15 : namespace Stats { 16 : 17 : /** 18 : * Runtime representation of an encoded stat name. 19 : */ 20 : class StatName; 21 : 22 : /** 23 : * Holds a set of symbols used to compose hierarhical names. 24 : */ 25 : class SymbolTable; 26 : 27 : /** 28 : * General interface for all stats objects. 29 : * 30 : * Note: some methods must match those in `PrimitiveMetricMetadata` because stats sinks 31 : * use templates to handle either type. The interface is not used for size/performance 32 : * reasons. 33 : */ 34 : class Metric : public RefcountInterface { 35 : public: 36 433485 : ~Metric() override = default; 37 : /** 38 : * Returns the full name of the Metric. This is intended for most uses, such 39 : * as streaming out the name to a stats sink or admin request, or comparing 40 : * against it in a test. Independent of the evolution of the data 41 : * representation for the name, this method will be available. For storing the 42 : * name as a map key, however, nameCStr() is a better choice, albeit one that 43 : * might change in the future to return a symbolized representation of the 44 : * elaborated string. 45 : */ 46 : virtual std::string name() const PURE; 47 : 48 : /** 49 : * Returns the full name of the Metric as an encoded array of symbols. 50 : */ 51 : virtual StatName statName() const PURE; 52 : 53 : /** 54 : * Returns a vector of configurable tags to identify this Metric. 55 : */ 56 : virtual TagVector tags() const PURE; 57 : 58 : /** 59 : * See a more detailed description in tagExtractedStatName(), which is the 60 : * preferred API to use when feasible. This API needs to compose the 61 : * std::string on the fly, and return it by value. 62 : * 63 : * @return The stat name with all tag values extracted, as a std::string. 64 : */ 65 : virtual std::string tagExtractedName() const PURE; 66 : 67 : /** 68 : * Returns the name of the Metric with the portions designated as tags removed 69 : * as a string. For example, The stat name "vhost.foo.vcluster.bar.c1" would 70 : * have "foo" extracted as the value of tag "vhost" and "bar" extracted as the 71 : * value of tag "vcluster". Thus the tagExtractedName is simply 72 : * "vhost.vcluster.c1". 73 : * 74 : * @return the name of the Metric with the portions designated as tags 75 : * removed. 76 : */ 77 : virtual StatName tagExtractedStatName() const PURE; 78 : 79 : // Function to be called from iterateTagStatNames passing name and value as StatNames. 80 : using TagStatNameIterFn = std::function<bool(StatName, StatName)>; 81 : 82 : /** 83 : * Iterates over all tags, calling a functor for each name/value pair. The 84 : * functor can return 'true' to continue or 'false' to stop the 85 : * iteration. 86 : * 87 : * @param fn The functor to call for StatName pair. 88 : */ 89 : virtual void iterateTagStatNames(const TagStatNameIterFn& fn) const PURE; 90 : 91 : // Function to be called from iterateTags passing name and value as const Tag&. 92 : using TagIterFn = std::function<bool(const Tag&)>; 93 : 94 : /** 95 : * Indicates whether this metric has been updated since the server was started. 96 : */ 97 : virtual bool used() const PURE; 98 : 99 : /** 100 : * Indicates whether this metric is hidden. 101 : */ 102 : virtual bool hidden() const PURE; 103 : 104 : /** 105 : * Flags: 106 : * Used: used by all stats types to figure out whether they have been used. 107 : * Logic...: used by gauges to cache how they should be combined with a parent's value. 108 : */ 109 : struct Flags { 110 : static constexpr uint8_t Used = 0x01; 111 : static constexpr uint8_t LogicAccumulate = 0x02; 112 : static constexpr uint8_t NeverImport = 0x04; 113 : static constexpr uint8_t Hidden = 0x08; 114 : }; 115 : virtual SymbolTable& symbolTable() PURE; 116 : virtual const SymbolTable& constSymbolTable() const PURE; 117 : }; 118 : 119 : /** 120 : * An always incrementing counter with latching capability. Each increment is added both to a 121 : * global counter as well as periodic counter. Calling latch() returns the periodic counter and 122 : * clears it. 123 : */ 124 : class Counter : public Metric { 125 : public: 126 317455 : ~Counter() override = default; 127 : 128 : virtual void add(uint64_t amount) PURE; 129 : virtual void inc() PURE; 130 : virtual uint64_t latch() PURE; 131 : virtual void reset() PURE; 132 : virtual uint64_t value() const PURE; 133 : }; 134 : 135 : using CounterSharedPtr = RefcountPtr<Counter>; 136 : 137 : /** 138 : * A gauge that can both increment and decrement. 139 : */ 140 : class Gauge : public Metric { 141 : public: 142 : // TODO(diazalan): Rename ImportMode to more generic name 143 : enum class ImportMode { 144 : Uninitialized, // Gauge was discovered during hot-restart transfer. 145 : NeverImport, // On hot-restart, each process starts with gauge at 0. 146 : Accumulate, // Transfers gauge state on hot-restart. 147 : HiddenAccumulate, // Will be transferred on hot-restart and ignored by admin/stats-sink 148 : }; 149 : 150 94084 : ~Gauge() override = default; 151 : 152 : virtual void add(uint64_t amount) PURE; 153 : virtual void dec() PURE; 154 : virtual void inc() PURE; 155 : virtual void set(uint64_t value) PURE; 156 : virtual void sub(uint64_t amount) PURE; 157 : virtual uint64_t value() const PURE; 158 : 159 : /** 160 : * Sets a value from a hot-restart parent. This parent contribution must be 161 : * kept distinct from the child value, so that when we erase the value it 162 : * is not commingled with the child value, which may have been set() directly. 163 : * 164 : * @param parent_value the value from the hot-restart parent. 165 : */ 166 : virtual void setParentValue(uint64_t parent_value) PURE; 167 : 168 : /** 169 : * @return the import mode, dictating behavior of the gauge across hot restarts. 170 : */ 171 : virtual ImportMode importMode() const PURE; 172 : 173 : /** 174 : * Gauges can be created with ImportMode::Uninitialized during hot-restart 175 : * merges, if they haven't yet been instantiated by the child process. When 176 : * they finally get instantiated, mergeImportMode should be called to 177 : * initialize the gauge's import mode. It is only valid to call 178 : * mergeImportMode when the current mode is ImportMode::Uninitialized. 179 : * 180 : * @param import_mode the new import mode. 181 : */ 182 : virtual void mergeImportMode(ImportMode import_mode) PURE; 183 : }; 184 : 185 : using GaugeSharedPtr = RefcountPtr<Gauge>; 186 : 187 : /** 188 : * A string, possibly non-ASCII. 189 : */ 190 : class TextReadout : public virtual Metric { 191 : public: 192 : // Text readout type is used internally to disambiguate isolated store 193 : // constructors. In the future we can extend it to specify text encoding or 194 : // some such. 195 : enum class Type { 196 : Default, // No particular meaning. 197 : }; 198 : 199 332 : ~TextReadout() override = default; 200 : 201 : /** 202 : * Sets the value of this TextReadout by moving the input |value| to minimize 203 : * buffer copies under the lock. 204 : */ 205 : virtual void set(absl::string_view value) PURE; 206 : /** 207 : * @return the copy of this TextReadout value. 208 : */ 209 : virtual std::string value() const PURE; 210 : }; 211 : 212 : using TextReadoutSharedPtr = RefcountPtr<TextReadout>; 213 : 214 : /** 215 : * Callback invoked to provide size of stats container. 216 : */ 217 : using SizeFn = std::function<void(std::size_t)>; 218 : 219 : /** 220 : * Callback invoked for each stat during iteration. 221 : */ 222 : template <typename Stat> using StatFn = std::function<void(Stat&)>; 223 : 224 : /** 225 : * Interface for stats lazy initialization. 226 : * To save memory and CPU consumption on blocks of stats that are never referenced throughout the 227 : * process lifetime, they can be encapsulated in a DeferredCreationCompatibleInterface. Then the 228 : Envoy 229 : * bootstrap configuration can be set to defer the instantiation of those block. Note that when the 230 : * blocks of stats are created, they carry an extra 60~100 byte overhead (depending on worker thread 231 : * count) due to internal bookkeeping data structures. The overhead when deferred stats are disabled 232 : * is just 8 bytes. 233 : * See more context: https://github.com/envoyproxy/envoy/issues/23575 234 : */ 235 : template <typename StatsStructType> class DeferredCreationCompatibleInterface { 236 : public: 237 : // Helper function to get-or-create and return the StatsStructType object. 238 : virtual StatsStructType& getOrCreate() PURE; 239 : 240 2376 : virtual ~DeferredCreationCompatibleInterface() = default; 241 : }; 242 : 243 : // A helper class for a lazy compatible stats struct type. 244 : template <typename StatsStructType> class DeferredCreationCompatibleStats { 245 : public: 246 : explicit DeferredCreationCompatibleStats( 247 : std::unique_ptr<DeferredCreationCompatibleInterface<StatsStructType>> d) 248 2376 : : data_(std::move(d)) {} 249 : // Allows move construct and assign. 250 : DeferredCreationCompatibleStats& operator=(DeferredCreationCompatibleStats&&) noexcept = default; 251 : DeferredCreationCompatibleStats(DeferredCreationCompatibleStats&&) noexcept = default; 252 : 253 1747 : inline StatsStructType* operator->() { return &data_->getOrCreate(); }; 254 782 : inline StatsStructType& operator*() { return data_->getOrCreate(); }; 255 : 256 : private: 257 : std::unique_ptr<DeferredCreationCompatibleInterface<StatsStructType>> data_; 258 : }; 259 : } // namespace Stats 260 : } // namespace Envoy