-
Notifications
You must be signed in to change notification settings - Fork 0
/
ProxyStats.h
234 lines (200 loc) · 6.55 KB
/
ProxyStats.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <mutex>
#include <folly/experimental/StringKeyedUnorderedMap.h>
#include "mcrouter/ExponentialSmoothData.h"
#include "mcrouter/PoolStats.h"
#include "mcrouter/stats.h"
namespace facebook {
namespace memcache {
namespace mcrouter {
class ProxyStats {
public:
explicit ProxyStats(const std::vector<std::string>& statsEnabledPools);
/**
* Aggregate proxy stat with the given index.
* Caller must be holding stats lock (i.e. must call lock() before).
*
* @param statId Index of the stat to aggregate.
*/
void aggregate(size_t statId);
/**
* Lock stats for the duration of the lock_guard life.
*/
std::unique_lock<std::mutex> lock() const;
ExponentialSmoothData<64>& durationUs() {
return durationUs_;
}
ExponentialSmoothData<64>& durationGetUs() {
return durationGetUs_;
}
ExponentialSmoothData<64>& durationUpdateUs() {
return durationUpdateUs_;
}
/**
* Tells the interval (in seconds) between closing a connection due to lack
* of activity and opening it again.
*/
ExponentialSmoothData<64>& inactiveConnectionClosedIntervalSec() {
return inactiveConnectionClosedIntervalSec_;
}
ExponentialSmoothData<64>& asyncLogDurationUs() {
return asyncLogDurationUs_;
}
size_t numBinsUsed() const {
return numBinsUsed_;
}
/**
* Return value of stat "statId" in the "timeBinIdx" time bin.
*
* @param statId Index of the stat.
* @param timeBinIdx Idx of the time bin.
*/
uint64_t getStatBinValue(size_t statId, size_t timeBinIdx) const {
return statsBin_[statId][timeBinIdx];
}
/**
* Return the aggregated value of stat "statId" in the past
* MOVING_AVERAGE_WINDOW_SIZE_IN_SECOND seconds.
* NOTE: This is only computed for rate_stats.
*
* @param statId Index of the stat.
*/
uint64_t getStatValueWithinWindow(size_t statId) const {
return statsNumWithinWindow_[statId];
}
/**
* Get the rate value of the stat "statId".
*
* @param statId Index of the stat.
*/
double getRateValue(size_t statId) const;
/**
* Increment the stat.
*
* @param stat Stat to increment
* @param amount Amount to increment the stat
*/
void increment(stat_name_t stat, int64_t amount = 1) {
stat_incr(stats_, stat, amount);
}
/**
* Decrement the stat.
*
* @param stat Stat to decrement
* @param amount Amount to decrement the stat
*/
void decrement(stat_name_t stat, int64_t amount = 1) {
increment(stat, -amount);
}
/**
* Increment the stat. Thread-safe.
*
* @param stat Stat to increment
* @param amount Amount to increment the stat
*/
void incrementSafe(stat_name_t stat, int64_t amount = 1) {
stat_incr_safe(stats_, stat, amount);
}
/**
* Decrement the stat. Thread-safe.
*
* @param stat Stat to decrement
* @param amount Amount to decrement the stat
*/
void decrementSafe(stat_name_t stat, int64_t amount = 1) {
incrementSafe(stat, -amount);
}
/**
* Set the stat value.
*
* @param stat Stat to set
* @param newValue New value of the stat
*/
void setValue(stat_name_t stat, int64_t newValue) {
stat_set_uint64(stats_, stat, newValue);
}
uint64_t getValue(stat_name_t stat) const {
return stat_get_uint64(stats_, stat);
}
uint64_t getConfigAge(uint64_t now) const {
return stat_get_config_age(stats_, now);
}
const stat_t& getStat(size_t statId) const {
return stats_[statId];
}
folly::StringKeyedUnorderedMap<stat_t> getAggregatedPoolStatsMap() const {
folly::StringKeyedUnorderedMap<stat_t> poolStatsMap;
for (const auto& poolStats : poolStats_) {
for (const auto& stat : poolStats.getStats()) {
poolStatsMap.emplace(stat.name, stat);
}
}
return poolStatsMap;
}
/**
* Returns pointer to the entry corresponding to the idx in
* the poolStats vector. If the idx is invalid, nullptr is returned
*
* @param idx
* @return pointer to poolStats vector entry
* nullptr if idx is invalid
*/
PoolStats* getPoolStats(int32_t idx) {
if (idx < 0 || static_cast<size_t>(idx) >= poolStats_.size()) {
return nullptr;
}
return &poolStats_[idx];
}
private:
mutable std::mutex mutex_;
stat_t stats_[num_stats]{};
// vector of the PoolStats
std::vector<PoolStats> poolStats_;
ExponentialSmoothData<64> durationUs_;
// Duration microseconds, broken down by get-like request type
ExponentialSmoothData<64> durationGetUs_;
// Duration microseconds, broken down by update-like request type
ExponentialSmoothData<64> durationUpdateUs_;
ExponentialSmoothData<64> inactiveConnectionClosedIntervalSec_;
// Time spent for asynclog spooling
ExponentialSmoothData<64> asyncLogDurationUs_;
// we are wasting some memory here to get faster mapping from stat name to
// statsBin_[] and statsNumWithinWindow_[] entry. i.e., the statsBin_[]
// and statsNumWithinWindow_[] entry for non-rate stat are not in use.
// we maintain some information for calculating average rate in the past
// MOVING_AVERAGE_WINDOW_SIZE_IN_SECOND seconds for every rate stat.
/*
* statsBin_[stat_name] is a circular array associated with stat "stat_name",
* where each element (statsBin_[stat_name][idx]) is either the count (if it
* is a rate_stat) or the max (if it is a max_stat) of "stat_name" in the
* "idx"th time bin. The updater thread updates these circular arrays once
* every MOVING_AVERAGE_WINDOW_SIZE_IN_SECOND second by setting the oldest
* time bin to stats[stat_name], and then reset stats[stat_name] to 0.
*/
uint64_t statsBin_[num_stats]
[MOVING_AVERAGE_WINDOW_SIZE_IN_SECOND /
MOVING_AVERAGE_BIN_SIZE_IN_SECOND]{};
/*
* statsNumWithinWindow_[stat_name] contains the count of stat "stat_name"
* in the past MOVING_AVERAGE_WINDOW_SIZE_IN_SECOND seconds. This array is
* also updated by the updater thread once every
* MOVING_AVERAGE_WINDOW_SIZE_IN_SECOND seconds
*/
uint64_t statsNumWithinWindow_[num_stats]{};
/*
* the number of bins currently used, which is initially set to 0, and is
* increased by 1 every MOVING_AVERAGE_WINDOW_SIZE_IN_SECOND seconds.
* numBinsUsed_ is at most MOVING_AVERAGE_WINDOW_SIZE_IN_SECOND /
* MOVING_AVERAGE_BIN_SIZE_IN_SECOND
*/
size_t numBinsUsed_{0};
};
} // namespace mcrouter
} // namespace memcache
} // namespace facebook