varz_stats.h
1 // Copyright 2013, Beeri 15. All rights reserved.
2 // Author: Roman Gershman (romange@gmail.com)
3 //
4 #pragma once
5 
6 #include <atomic>
7 #include <functional>
8 #include <mutex>
9 
10 #include "absl/strings/str_cat.h" // for absl::AlphaNum
11 #include "base/atomic_wrapper.h"
12 #include "base/integral_types.h"
13 #include "strings/stringpiece.h"
14 #include "strings/unique_strings.h"
15 #include "util/stats/sliding_counter.h"
16 #include "util/stats/varz_node.h"
17 
18 #define DEFINE_VARZ(type, name) util::type name(#name)
19 
20 namespace util {
21 
25 class VarzMapCount : public VarzListNode {
26  typedef StringPieceDenseMap<base::atomic_wrapper<long>> Map;
27 
28  public:
29  explicit VarzMapCount(const char* varname) : VarzListNode(varname) {
30  map_counts_.set_empty_key(StringPiece());
31  }
32 
33  // Increments key by delta.
34  void IncBy(StringPiece key, int32 delta);
35 
36  void Inc(StringPiece key) {
37  IncBy(key, 1);
38  }
39  void Set(StringPiece key, int32 value);
40 
41  private:
42  virtual AnyValue GetData() const override;
43  Map::iterator ReadLockAndFindOrInsert(StringPiece key);
44 
45  mutable folly::RWSpinLock rw_spinlock_;
46  StringPieceDenseMap<base::atomic_wrapper<long>> map_counts_;
47 };
48 
49 // represents a family of averages over 5min period.
51  public:
52  explicit VarzMapAverage5m(const char* varname) : VarzListNode(varname) {
53  avg_.set_empty_key(StringPiece());
54  }
55 
56  void IncBy(StringPiece key, int32 delta);
57 
58  private:
59  virtual AnyValue GetData() const override;
60 
61  mutable std::mutex mutex_;
62 
64  StringPieceDenseMap<std::pair<Counter, Counter>> avg_;
65 };
66 
67 class VarzCount : public VarzListNode {
68  public:
69  explicit VarzCount(const char* varname) : VarzListNode(varname), val_(0) {
70  }
71 
72  void IncBy(int32 delta) {
73  val_ += delta;
74  }
75  void Inc() {
76  IncBy(1);
77  }
78 
79  private:
80  virtual AnyValue GetData() const override;
81 
82  std::atomic_long val_;
83 };
84 
85 class VarzQps : public VarzListNode {
86  public:
87  explicit VarzQps(const char* varname) : VarzListNode(varname) {
88  }
89 
90  void Inc() {
91  val_.Inc();
92  }
93 
94  private:
95  virtual AnyValue GetData() const override;
96 
97  mutable util::QPSCount val_;
98 };
99 
100 class VarzFunction : public VarzListNode {
101  public:
102  typedef AnyValue::Map KeyValMap;
103  typedef std::function<KeyValMap()> MapCb;
104 
105  // cb - function that formats the output either as json or html according to the boolean is_json.
106  explicit VarzFunction(const char* varname, MapCb cb) : VarzListNode(varname), cb_(cb) {
107  }
108 
109  private:
110  AnyValue GetData() const override;
111 
112  MapCb cb_;
113 };
114 
115 // Increments non-trivial key in VarzMapCount described by base and suffix.
116 // Does it efficiently and avoids allocations.
117 // The caller must make sure that N is large enough to contain the key.
118 template <int N> class FastVarMapCounter {
119  VarzMapCount& map_count_;
120 
121  char buf_[N];
122  char* suffix_;
123 
124  public:
125  FastVarMapCounter(VarzMapCount* map_count, std::initializer_list<absl::AlphaNum> base)
126  : map_count_(*map_count) {
127  suffix_ = StrAppend(buf_, N, base);
128  }
129 
130  void Inc(const char* suffix) {
131  IncBy(suffix, 1);
132  }
133 
134  void IncBy(const char* suffix, int32 val) {
135  strcpy(suffix_, suffix);
136  map_count_.IncBy(buf_, val);
137  }
138 };
139 
140 } // namespace util