varz_stats.cc
1 // Copyright 2013, Beeri 15. All rights reserved.
2 // Author: Roman Gershman (romange@gmail.com)
3 //
4 
5 #include "util/stats/varz_stats.h"
6 
7 #include "base/walltime.h"
8 #include "strings/strcat.h"
9 #include "strings/stringprintf.h"
10 
11 using std::string;
12 using strings::AsString;
13 
14 namespace util {
15 
16 auto VarzMapCount::ReadLockAndFindOrInsert(StringPiece key) -> Map::iterator {
17  rw_spinlock_.lock_shared();
18  auto it = map_counts_.find(key);
19  if (it != map_counts_.end())
20  return it;
21 
22  rw_spinlock_.unlock_shared();
23 
24  rw_spinlock_.lock();
25  auto res = map_counts_.emplace(key, base::atomic_wrapper<long>(0));
26  rw_spinlock_.unlock_and_lock_shared();
27  return res.first;
28 }
29 
30 void VarzMapCount::IncBy(StringPiece key, int32 delta) {
31  if (key.empty()) {
32  LOG(DFATAL) << "Empty varz key";
33  return;
34  }
35 
36  if (!delta) {
37  return;
38  }
39 
40  auto it = ReadLockAndFindOrInsert(key);
41  it->second.fetch_add(delta, std::memory_order_relaxed);
42  rw_spinlock_.unlock_shared();
43 }
44 
45 void VarzMapCount::Set(StringPiece key, int32 value) {
46  if (key.empty()) {
47  LOG(DFATAL) << "Empty varz key";
48  return;
49  }
50 
51  auto it = ReadLockAndFindOrInsert(key);
52  it->second.store(value, std::memory_order_relaxed);
53  rw_spinlock_.unlock_shared();
54 }
55 
56 VarzValue VarzMapCount::GetData() const {
57  AnyValue::Map result;
58  rw_spinlock_.lock_shared();
59  for (const auto& k_v : map_counts_) {
60  result.emplace_back(AsString(k_v.first), VarzValue::FromInt(k_v.second));
61  }
62  rw_spinlock_.unlock_shared();
63  typedef AnyValue::Map::value_type vt;
64  std::sort(result.begin(), result.end(),
65  [](const vt& l, const vt& r) { return l.first < r.first; });
66 
67  return AnyValue{std::move(result)};
68 }
69 
70 VarzValue VarzMapAverage5m::GetData() const {
71  std::lock_guard<std::mutex> lock(mutex_);
72  AnyValue::Map result;
73 
74  for (const auto& k_v : avg_) {
75  AnyValue::Map items;
76  int64 count = k_v.second.second.Sum();
77  int64 sum = k_v.second.first.Sum();
78  items.emplace_back("count", VarzValue::FromInt(count));
79  items.emplace_back("sum", VarzValue::FromInt(sum));
80 
81  double avg = count > 0 ? double(sum) / count : 0;
82  items.emplace_back("average", VarzValue::FromDouble(avg));
83 
84  result.emplace_back(AsString(k_v.first), AnyValue(items));
85  }
86 
87  return AnyValue{std::move(result)};
88 }
89 
90 void VarzMapAverage5m::IncBy(StringPiece key, int32 delta) {
91  std::lock_guard<std::mutex> lock(mutex_);
92  auto& val = avg_[key];
93  val.first.IncBy(delta);
94  val.second.Inc();
95 }
96 
97 VarzValue VarzCount::GetData() const {
98  return VarzValue::FromInt(val_.load());
99 }
100 
101 VarzValue VarzQps::GetData() const {
102  return VarzValue::FromInt(val_.Get());
103 }
104 
105 VarzValue VarzFunction::GetData() const {
106  AnyValue::Map result = cb_();
107  return AnyValue(result);
108 }
109 
110 } // namespace util