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
1208619
  PrimitiveCounter() = default;
23

            
24
552
  uint64_t value() const { return value_; }
25

            
26
121708
  void add(uint64_t amount) {
27
121708
    value_ += amount;
28
121708
    pending_increment_ += amount;
29
121708
  }
30
121627
  void inc() { add(1); }
31
  void reset() { value_ = 0; }
32
427
  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
402948
  PrimitiveGauge() = default;
47

            
48
18432741
  uint64_t value() const { return value_; }
49

            
50
80252
  void add(uint64_t amount) { value_ += amount; }
51
80192
  void dec() { sub(1); }
52
80188
  void inc() { add(1); }
53
114
  void set(uint64_t value) { value_ = value; }
54
80192
  void sub(uint64_t amount) {
55
80192
    ASSERT(value_ >= amount);
56
80192
    value_ -= amount;
57
80192
  }
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
46
  const std::string& tagExtractedName() const { return tag_extracted_name_; }
70
158
  const std::string& name() const { return name_; }
71
52
  const Stats::TagVector& tags() const { return tags_; }
72
  bool used() const { return true; }
73
63
  bool hidden() const { return false; }
74

            
75
164
  void setName(std::string&& name) { name_ = std::move(name); }
76
162
  void setTagExtractedName(std::string&& tag_extracted_name) {
77
162
    tag_extracted_name_ = std::move(tag_extracted_name);
78
162
  }
79
162
  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
68
      : value_(counter.value()), delta_(counter.latch()) {}
91

            
92
43
  uint64_t value() const { return value_; }
93
11
  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
98
  PrimitiveGaugeSnapshot(PrimitiveGauge& gauge) : value_(gauge.value()) {}
103

            
104
64
  uint64_t value() const { return value_; }
105

            
106
private:
107
  const uint64_t value_;
108
};
109

            
110
} // namespace Stats
111
} // namespace Envoy