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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab ft=cpp
#include "rgw_perf_counters.h"
#include "common/perf_counters.h"
#include "common/perf_counters_key.h"
#include "common/ceph_context.h"
#include "rgw_sal.h"
using namespace ceph::perf_counters;
using namespace rgw::op_counters;
using namespace rgw::persistent_topic_counters;
PerfCounters *perfcounter = NULL;
void add_rgw_frontend_counters(PerfCountersBuilder *pcb) {
// RGW emits comparatively few metrics, so let's be generous
// and mark them all USEFUL to get transmission to ceph-mgr by default.
pcb->set_prio_default(PerfCountersBuilder::PRIO_USEFUL);
pcb->add_u64_counter(l_rgw_req, "req", "Requests");
pcb->add_u64_counter(l_rgw_failed_req, "failed_req", "Aborted requests");
pcb->add_u64(l_rgw_qlen, "qlen", "Queue length");
pcb->add_u64(l_rgw_qactive, "qactive", "Active requests queue");
pcb->add_u64_counter(l_rgw_cache_hit, "cache_hit", "Cache hits");
pcb->add_u64_counter(l_rgw_cache_miss, "cache_miss", "Cache miss");
pcb->add_u64_counter(l_rgw_keystone_token_cache_hit, "keystone_token_cache_hit", "Keystone token cache hits");
pcb->add_u64_counter(l_rgw_keystone_token_cache_miss, "keystone_token_cache_miss", "Keystone token cache miss");
pcb->add_u64_counter(l_rgw_gc_retire, "gc_retire_object", "GC object retires");
pcb->add_u64_counter(l_rgw_lc_expire_current, "lc_expire_current",
"Lifecycle current expiration");
pcb->add_u64_counter(l_rgw_lc_expire_noncurrent, "lc_expire_noncurrent",
"Lifecycle non-current expiration");
pcb->add_u64_counter(l_rgw_lc_expire_dm, "lc_expire_dm",
"Lifecycle delete-marker expiration");
pcb->add_u64_counter(l_rgw_lc_transition_current, "lc_transition_current",
"Lifecycle current transition");
pcb->add_u64_counter(l_rgw_lc_transition_noncurrent,
"lc_transition_noncurrent",
"Lifecycle non-current transition");
pcb->add_u64_counter(l_rgw_lc_abort_mpu, "lc_abort_mpu",
"Lifecycle abort multipart upload");
pcb->add_u64_counter(l_rgw_pubsub_event_triggered, "pubsub_event_triggered", "Pubsub events with at least one topic");
pcb->add_u64_counter(l_rgw_pubsub_event_lost, "pubsub_event_lost", "Pubsub events lost");
pcb->add_u64_counter(l_rgw_pubsub_store_ok, "pubsub_store_ok", "Pubsub events successfully stored");
pcb->add_u64_counter(l_rgw_pubsub_store_fail, "pubsub_store_fail", "Pubsub events failed to be stored");
pcb->add_u64(l_rgw_pubsub_events, "pubsub_events", "Pubsub events in store");
pcb->add_u64_counter(l_rgw_pubsub_push_ok, "pubsub_push_ok", "Pubsub events pushed to an endpoint");
pcb->add_u64_counter(l_rgw_pubsub_push_failed, "pubsub_push_failed", "Pubsub events failed to be pushed to an endpoint");
pcb->add_u64(l_rgw_pubsub_push_pending, "pubsub_push_pending", "Pubsub events pending reply from endpoint");
pcb->add_u64_counter(l_rgw_pubsub_missing_conf, "pubsub_missing_conf", "Pubsub events could not be handled because of missing configuration");
pcb->add_u64_counter(l_rgw_lua_script_ok, "lua_script_ok", "Successfull executions of Lua scripts");
pcb->add_u64_counter(l_rgw_lua_script_fail, "lua_script_fail", "Failed executions of Lua scripts");
pcb->add_u64(l_rgw_lua_current_vms, "lua_current_vms", "Number of Lua VMs currently being executed");
}
void add_rgw_op_counters(PerfCountersBuilder *lpcb) {
// description must match general rgw counters description above
lpcb->set_prio_default(PerfCountersBuilder::PRIO_USEFUL);
lpcb->add_u64_counter(l_rgw_op_put_obj, "put_obj_ops", "Puts");
lpcb->add_u64_counter(l_rgw_op_put_obj_b, "put_obj_bytes", "Size of puts");
lpcb->add_time_avg(l_rgw_op_put_obj_lat, "put_obj_lat", "Put latency");
lpcb->add_u64_counter(l_rgw_op_get_obj, "get_obj_ops", "Gets");
lpcb->add_u64_counter(l_rgw_op_get_obj_b, "get_obj_bytes", "Size of gets");
lpcb->add_time_avg(l_rgw_op_get_obj_lat, "get_obj_lat", "Get latency");
lpcb->add_u64_counter(l_rgw_op_del_obj, "del_obj_ops", "Delete objects");
lpcb->add_u64_counter(l_rgw_op_del_obj_b, "del_obj_bytes", "Size of delete objects");
lpcb->add_time_avg(l_rgw_op_del_obj_lat, "del_obj_lat", "Delete object latency");
lpcb->add_u64_counter(l_rgw_op_del_bucket, "del_bucket_ops", "Delete Buckets");
lpcb->add_time_avg(l_rgw_op_del_bucket_lat, "del_bucket_lat", "Delete bucket latency");
lpcb->add_u64_counter(l_rgw_op_copy_obj, "copy_obj_ops", "Copy objects");
lpcb->add_u64_counter(l_rgw_op_copy_obj_b, "copy_obj_bytes", "Size of copy objects");
lpcb->add_time_avg(l_rgw_op_copy_obj_lat, "copy_obj_lat", "Copy object latency");
lpcb->add_u64_counter(l_rgw_op_list_obj, "list_obj_ops", "List objects");
lpcb->add_time_avg(l_rgw_op_list_obj_lat, "list_obj_lat", "List objects latency");
lpcb->add_u64_counter(l_rgw_op_list_buckets, "list_buckets_ops", "List buckets");
lpcb->add_time_avg(l_rgw_op_list_buckets_lat, "list_buckets_lat", "List buckets latency");
}
void add_rgw_topic_counters(PerfCountersBuilder *lpcb) {
lpcb->set_prio_default(PerfCountersBuilder::PRIO_USEFUL);
lpcb->add_u64(l_rgw_persistent_topic_len, "persistent_topic_len", "Persistent topic queue length");
lpcb->add_u64(l_rgw_persistent_topic_size, "persistent_topic_size", "Persistent topic queue size");
}
void frontend_counters_init(CephContext *cct) {
PerfCountersBuilder pcb(cct, "rgw", l_rgw_first, l_rgw_last);
add_rgw_frontend_counters(&pcb);
PerfCounters *new_counters = pcb.create_perf_counters();
cct->get_perfcounters_collection()->add(new_counters);
perfcounter = new_counters;
}
namespace rgw::op_counters {
ceph::perf_counters::PerfCountersCache *user_counters_cache = NULL;
ceph::perf_counters::PerfCountersCache *bucket_counters_cache = NULL;
PerfCounters *global_op_counters = NULL;
const std::string rgw_op_counters_key = "rgw_op";
std::shared_ptr<PerfCounters> create_rgw_op_counters(const std::string& name, CephContext *cct) {
std::string_view key = ceph::perf_counters::key_name(name);
ceph_assert(rgw_op_counters_key == key);
PerfCountersBuilder pcb(cct, name, l_rgw_op_first, l_rgw_op_last);
add_rgw_op_counters(&pcb);
std::shared_ptr<PerfCounters> new_counters(pcb.create_perf_counters());
cct->get_perfcounters_collection()->add(new_counters.get());
return new_counters;
}
void global_op_counters_init(CephContext *cct) {
PerfCountersBuilder pcb(cct, rgw_op_counters_key, l_rgw_op_first, l_rgw_op_last);
add_rgw_op_counters(&pcb);
PerfCounters *new_counters = pcb.create_perf_counters();
cct->get_perfcounters_collection()->add(new_counters);
global_op_counters = new_counters;
}
CountersContainer get(req_state *s) {
CountersContainer counters;
std::string key;
if (user_counters_cache && !s->user->get_id().id.empty()) {
if (s->user->get_tenant().empty()) {
key = ceph::perf_counters::key_create(rgw_op_counters_key, {{"User", s->user->get_id().id}});
} else {
key = ceph::perf_counters::key_create(rgw_op_counters_key, {{"User", s->user->get_id().id}, {"Tenant", s->user->get_tenant()}});
}
counters.user_counters = user_counters_cache->get(key);
}
if (bucket_counters_cache && !s->bucket_name.empty()) {
if (s->bucket_tenant.empty()) {
key = ceph::perf_counters::key_create(rgw_op_counters_key, {{"Bucket", s->bucket_name}});
} else {
key = ceph::perf_counters::key_create(rgw_op_counters_key, {{"Bucket", s->bucket_name}, {"Tenant", s->bucket_tenant}});
}
counters.bucket_counters = bucket_counters_cache->get(key);
}
return counters;
}
void inc(const CountersContainer &counters, int idx, uint64_t v) {
if (counters.user_counters) {
PerfCounters *user_counters = counters.user_counters.get();
user_counters->inc(idx, v);
}
if (counters.bucket_counters) {
PerfCounters *bucket_counters = counters.bucket_counters.get();
bucket_counters->inc(idx, v);
}
if (global_op_counters) {
global_op_counters->inc(idx, v);
}
}
void tinc(const CountersContainer &counters, int idx, utime_t amt) {
if (counters.user_counters) {
PerfCounters *user_counters = counters.user_counters.get();
user_counters->tinc(idx, amt);
}
if (counters.bucket_counters) {
PerfCounters *bucket_counters = counters.bucket_counters.get();
bucket_counters->tinc(idx, amt);
}
if (global_op_counters) {
global_op_counters->tinc(idx, amt);
}
}
void tinc(const CountersContainer &counters, int idx, ceph::timespan amt) {
if (counters.user_counters) {
PerfCounters *user_counters = counters.user_counters.get();
user_counters->tinc(idx, amt);
}
if (counters.bucket_counters) {
PerfCounters *bucket_counters = counters.bucket_counters.get();
bucket_counters->tinc(idx, amt);
}
if (global_op_counters) {
global_op_counters->tinc(idx, amt);
}
}
} // namespace rgw::op_counters
namespace rgw::persistent_topic_counters {
const std::string rgw_topic_counters_key = "rgw_topic";
CountersManager::CountersManager(const std::string& topic_name, CephContext *cct)
: cct(cct)
{
const std::string topic_key = ceph::perf_counters::key_create(rgw_topic_counters_key, {{"Topic", topic_name}});
PerfCountersBuilder pcb(cct, topic_key, l_rgw_topic_first, l_rgw_topic_last);
add_rgw_topic_counters(&pcb);
topic_counters = std::unique_ptr<PerfCounters>(pcb.create_perf_counters());
cct->get_perfcounters_collection()->add(topic_counters.get());
}
void CountersManager::set(int idx, uint64_t v) {
topic_counters->set(idx, v);
}
CountersManager::~CountersManager() {
cct->get_perfcounters_collection()->remove(topic_counters.get());
}
} // namespace rgw::persistent_topic_counters
int rgw_perf_start(CephContext *cct)
{
frontend_counters_init(cct);
bool user_counters_cache_enabled = cct->_conf.get_val<bool>("rgw_user_counters_cache");
if (user_counters_cache_enabled) {
uint64_t target_size = cct->_conf.get_val<uint64_t>("rgw_user_counters_cache_size");
user_counters_cache = new PerfCountersCache(cct, target_size, create_rgw_op_counters);
}
bool bucket_counters_cache_enabled = cct->_conf.get_val<bool>("rgw_bucket_counters_cache");
if (bucket_counters_cache_enabled) {
uint64_t target_size = cct->_conf.get_val<uint64_t>("rgw_bucket_counters_cache_size");
bucket_counters_cache = new PerfCountersCache(cct, target_size, create_rgw_op_counters);
}
global_op_counters_init(cct);
return 0;
}
void rgw_perf_stop(CephContext *cct)
{
ceph_assert(perfcounter);
cct->get_perfcounters_collection()->remove(perfcounter);
delete perfcounter;
ceph_assert(global_op_counters);
cct->get_perfcounters_collection()->remove(global_op_counters);
delete global_op_counters;
delete user_counters_cache;
delete bucket_counters_cache;
}
|