Line data Source code
1 : #pragma once 2 : 3 : #include <string> 4 : 5 : #include "envoy/stats/tag.h" 6 : 7 : #include "source/common/common/assert.h" 8 : #include "source/common/common/non_copyable.h" 9 : 10 : #include "absl/strings/string_view.h" 11 : 12 : namespace Envoy { 13 : namespace Stats { 14 : 15 : /** 16 : * Primitive, low-memory-overhead counter with incrementing and latching capabilities. Each 17 : * increment is added both to a global counter as well as periodic counter. Calling latch() 18 : * returns the periodic counter and clears it. 19 : */ 20 : class PrimitiveCounter : NonCopyable { 21 : public: 22 1092798 : PrimitiveCounter() = default; 23 : 24 0 : uint64_t value() const { return value_; } 25 : 26 567 : void add(uint64_t amount) { 27 567 : value_ += amount; 28 567 : pending_increment_ += amount; 29 567 : } 30 567 : void inc() { add(1); } 31 0 : void reset() { value_ = 0; } 32 0 : uint64_t latch() { return pending_increment_.exchange(0); } 33 : 34 : private: 35 : std::atomic<uint64_t> value_{0}; 36 : std::atomic<uint64_t> pending_increment_{0}; 37 : }; 38 : 39 : using PrimitiveCounterReference = std::reference_wrapper<PrimitiveCounter>; 40 : 41 : /** 42 : * Primitive, low-memory-overhead gauge with increment and decrement capabilities. 43 : */ 44 : class PrimitiveGauge : NonCopyable { 45 : public: 46 364266 : PrimitiveGauge() = default; 47 : 48 2081007 : uint64_t value() const { return value_; } 49 : 50 375 : void add(uint64_t amount) { value_ += amount; } 51 375 : void dec() { sub(1); } 52 375 : void inc() { add(1); } 53 626756 : void set(uint64_t value) { value_ = value; } 54 375 : void sub(uint64_t amount) { 55 375 : ASSERT(value_ >= amount); 56 375 : value_ -= amount; 57 375 : } 58 : 59 : private: 60 : std::atomic<uint64_t> value_{0}; 61 : }; 62 : 63 : using PrimitiveGaugeReference = std::reference_wrapper<PrimitiveGauge>; 64 : 65 : class PrimitiveMetricMetadata { 66 : public: 67 : // Mirror some of the API for Stats::Metric for use in templates that 68 : // accept either Counter/Gauge or PrimitiveCounterSnapshot/PrimitiveGaugeSnapshot. 69 0 : const std::string& tagExtractedName() const { return tag_extracted_name_; } 70 0 : const std::string& name() const { return name_; } 71 0 : const Stats::TagVector& tags() const { return tags_; } 72 0 : bool used() const { return true; } 73 0 : bool hidden() const { return false; } 74 : 75 0 : void setName(std::string&& name) { name_ = std::move(name); } 76 0 : void setTagExtractedName(std::string&& tag_extracted_name) { 77 0 : tag_extracted_name_ = std::move(tag_extracted_name); 78 0 : } 79 0 : void setTags(const Stats::TagVector& tags) { tags_ = tags; } 80 : 81 : private: 82 : std::string name_; 83 : std::string tag_extracted_name_; 84 : Stats::TagVector tags_; 85 : }; 86 : 87 : class PrimitiveCounterSnapshot : public PrimitiveMetricMetadata { 88 : public: 89 : PrimitiveCounterSnapshot(PrimitiveCounter& counter) 90 0 : : value_(counter.value()), delta_(counter.latch()) {} 91 : 92 0 : uint64_t value() const { return value_; } 93 0 : uint64_t delta() const { return delta_; } 94 : 95 : private: 96 : const uint64_t value_; 97 : const uint64_t delta_; 98 : }; 99 : 100 : class PrimitiveGaugeSnapshot : public PrimitiveMetricMetadata { 101 : public: 102 0 : PrimitiveGaugeSnapshot(PrimitiveGauge& gauge) : value_(gauge.value()) {} 103 : 104 0 : uint64_t value() const { return value_; } 105 : 106 : private: 107 : const uint64_t value_; 108 : }; 109 : 110 : } // namespace Stats 111 : } // namespace Envoy