]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2011 New Dream Network | |
7 | * Copyright (C) 2017 OVH | |
8 | * | |
9 | * This is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU Lesser General Public | |
11 | * License version 2.1, as published by the Free Software | |
12 | * Foundation. See file COPYING. | |
13 | * | |
14 | */ | |
15 | ||
7c673cae FG |
16 | #include "common/perf_counters.h" |
17 | #include "common/dout.h" | |
7c673cae | 18 | #include "common/valgrind.h" |
9f95a23c | 19 | #include "include/common_fwd.h" |
7c673cae | 20 | |
7c673cae FG |
21 | using std::ostringstream; |
22 | ||
9f95a23c | 23 | namespace TOPNSPC::common { |
11fdf7f2 | 24 | PerfCountersCollectionImpl::PerfCountersCollectionImpl() |
7c673cae FG |
25 | { |
26 | } | |
27 | ||
11fdf7f2 | 28 | PerfCountersCollectionImpl::~PerfCountersCollectionImpl() |
7c673cae FG |
29 | { |
30 | clear(); | |
31 | } | |
32 | ||
11fdf7f2 | 33 | void PerfCountersCollectionImpl::add(PerfCounters *l) |
7c673cae | 34 | { |
7c673cae FG |
35 | // make sure the name is unique |
36 | perf_counters_set_t::iterator i; | |
37 | i = m_loggers.find(l); | |
38 | while (i != m_loggers.end()) { | |
39 | ostringstream ss; | |
40 | ss << l->get_name() << "-" << (void*)l; | |
41 | l->set_name(ss.str()); | |
42 | i = m_loggers.find(l); | |
43 | } | |
44 | ||
45 | m_loggers.insert(l); | |
46 | ||
47 | for (unsigned int i = 0; i < l->m_data.size(); ++i) { | |
48 | PerfCounters::perf_counter_data_any_d &data = l->m_data[i]; | |
49 | ||
50 | std::string path = l->get_name(); | |
51 | path += "."; | |
52 | path += data.name; | |
53 | ||
3efd9988 | 54 | by_path[path] = {&data, l}; |
7c673cae FG |
55 | } |
56 | } | |
57 | ||
11fdf7f2 | 58 | void PerfCountersCollectionImpl::remove(PerfCounters *l) |
7c673cae | 59 | { |
7c673cae FG |
60 | for (unsigned int i = 0; i < l->m_data.size(); ++i) { |
61 | PerfCounters::perf_counter_data_any_d &data = l->m_data[i]; | |
62 | ||
63 | std::string path = l->get_name(); | |
64 | path += "."; | |
65 | path += data.name; | |
66 | ||
67 | by_path.erase(path); | |
68 | } | |
69 | ||
70 | perf_counters_set_t::iterator i = m_loggers.find(l); | |
11fdf7f2 | 71 | ceph_assert(i != m_loggers.end()); |
7c673cae FG |
72 | m_loggers.erase(i); |
73 | } | |
74 | ||
11fdf7f2 | 75 | void PerfCountersCollectionImpl::clear() |
7c673cae | 76 | { |
7c673cae FG |
77 | perf_counters_set_t::iterator i = m_loggers.begin(); |
78 | perf_counters_set_t::iterator i_end = m_loggers.end(); | |
79 | for (; i != i_end; ) { | |
11fdf7f2 | 80 | delete *i; |
7c673cae FG |
81 | m_loggers.erase(i++); |
82 | } | |
83 | ||
84 | by_path.clear(); | |
85 | } | |
86 | ||
11fdf7f2 | 87 | bool PerfCountersCollectionImpl::reset(const std::string &name) |
7c673cae FG |
88 | { |
89 | bool result = false; | |
7c673cae FG |
90 | perf_counters_set_t::iterator i = m_loggers.begin(); |
91 | perf_counters_set_t::iterator i_end = m_loggers.end(); | |
92 | ||
93 | if (!strcmp(name.c_str(), "all")) { | |
94 | while (i != i_end) { | |
95 | (*i)->reset(); | |
96 | ++i; | |
97 | } | |
98 | result = true; | |
99 | } else { | |
100 | while (i != i_end) { | |
101 | if (!name.compare((*i)->get_name())) { | |
102 | (*i)->reset(); | |
103 | result = true; | |
104 | break; | |
105 | } | |
106 | ++i; | |
107 | } | |
108 | } | |
109 | ||
110 | return result; | |
111 | } | |
112 | ||
113 | ||
114 | /** | |
115 | * Serialize current values of performance counters. Optionally | |
116 | * output the schema instead, or filter output to a particular | |
117 | * PerfCounters or particular named counter. | |
118 | * | |
119 | * @param logger name of subsystem logger, e.g. "mds_cache", may be empty | |
120 | * @param counter name of counter within subsystem, e.g. "num_strays", | |
121 | * may be empty. | |
122 | * @param schema if true, output schema instead of current data. | |
123 | * @param histograms if true, dump histogram values, | |
124 | * if false dump all non-histogram counters | |
125 | */ | |
11fdf7f2 | 126 | void PerfCountersCollectionImpl::dump_formatted_generic( |
7c673cae FG |
127 | Formatter *f, |
128 | bool schema, | |
129 | bool histograms, | |
130 | const std::string &logger, | |
eafe8130 | 131 | const std::string &counter) const |
7c673cae | 132 | { |
7c673cae FG |
133 | f->open_object_section("perfcounter_collection"); |
134 | ||
135 | for (perf_counters_set_t::iterator l = m_loggers.begin(); | |
136 | l != m_loggers.end(); ++l) { | |
137 | // Optionally filter on logger name, pass through counter filter | |
138 | if (logger.empty() || (*l)->get_name() == logger) { | |
139 | (*l)->dump_formatted_generic(f, schema, histograms, counter); | |
140 | } | |
141 | } | |
142 | f->close_section(); | |
143 | } | |
144 | ||
11fdf7f2 TL |
145 | void PerfCountersCollectionImpl::with_counters(std::function<void( |
146 | const PerfCountersCollectionImpl::CounterMap &)> fn) const | |
7c673cae | 147 | { |
7c673cae FG |
148 | fn(by_path); |
149 | } | |
150 | ||
151 | // --------------------------- | |
152 | ||
153 | PerfCounters::~PerfCounters() | |
154 | { | |
155 | } | |
156 | ||
157 | void PerfCounters::inc(int idx, uint64_t amt) | |
158 | { | |
11fdf7f2 | 159 | #ifndef WITH_SEASTAR |
7c673cae FG |
160 | if (!m_cct->_conf->perf) |
161 | return; | |
11fdf7f2 | 162 | #endif |
7c673cae | 163 | |
11fdf7f2 TL |
164 | ceph_assert(idx > m_lower_bound); |
165 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
166 | perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
167 | if (!(data.type & PERFCOUNTER_U64)) | |
168 | return; | |
169 | if (data.type & PERFCOUNTER_LONGRUNAVG) { | |
31f18b77 FG |
170 | data.avgcount++; |
171 | data.u64 += amt; | |
172 | data.avgcount2++; | |
7c673cae | 173 | } else { |
31f18b77 | 174 | data.u64 += amt; |
7c673cae FG |
175 | } |
176 | } | |
177 | ||
178 | void PerfCounters::dec(int idx, uint64_t amt) | |
179 | { | |
11fdf7f2 | 180 | #ifndef WITH_SEASTAR |
7c673cae FG |
181 | if (!m_cct->_conf->perf) |
182 | return; | |
11fdf7f2 | 183 | #endif |
7c673cae | 184 | |
11fdf7f2 TL |
185 | ceph_assert(idx > m_lower_bound); |
186 | ceph_assert(idx < m_upper_bound); | |
7c673cae | 187 | perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
11fdf7f2 | 188 | ceph_assert(!(data.type & PERFCOUNTER_LONGRUNAVG)); |
7c673cae FG |
189 | if (!(data.type & PERFCOUNTER_U64)) |
190 | return; | |
31f18b77 | 191 | data.u64 -= amt; |
7c673cae FG |
192 | } |
193 | ||
194 | void PerfCounters::set(int idx, uint64_t amt) | |
195 | { | |
11fdf7f2 | 196 | #ifndef WITH_SEASTAR |
7c673cae FG |
197 | if (!m_cct->_conf->perf) |
198 | return; | |
11fdf7f2 | 199 | #endif |
7c673cae | 200 | |
11fdf7f2 TL |
201 | ceph_assert(idx > m_lower_bound); |
202 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
203 | perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
204 | if (!(data.type & PERFCOUNTER_U64)) | |
205 | return; | |
206 | ||
207 | ANNOTATE_BENIGN_RACE_SIZED(&data.u64, sizeof(data.u64), | |
208 | "perf counter atomic"); | |
209 | if (data.type & PERFCOUNTER_LONGRUNAVG) { | |
31f18b77 FG |
210 | data.avgcount++; |
211 | data.u64 = amt; | |
212 | data.avgcount2++; | |
7c673cae | 213 | } else { |
31f18b77 | 214 | data.u64 = amt; |
7c673cae FG |
215 | } |
216 | } | |
217 | ||
218 | uint64_t PerfCounters::get(int idx) const | |
219 | { | |
11fdf7f2 | 220 | #ifndef WITH_SEASTAR |
7c673cae FG |
221 | if (!m_cct->_conf->perf) |
222 | return 0; | |
11fdf7f2 | 223 | #endif |
7c673cae | 224 | |
11fdf7f2 TL |
225 | ceph_assert(idx > m_lower_bound); |
226 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
227 | const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
228 | if (!(data.type & PERFCOUNTER_U64)) | |
229 | return 0; | |
31f18b77 | 230 | return data.u64; |
7c673cae FG |
231 | } |
232 | ||
11fdf7f2 | 233 | void PerfCounters::tinc(int idx, utime_t amt) |
7c673cae | 234 | { |
11fdf7f2 | 235 | #ifndef WITH_SEASTAR |
7c673cae FG |
236 | if (!m_cct->_conf->perf) |
237 | return; | |
11fdf7f2 | 238 | #endif |
7c673cae | 239 | |
11fdf7f2 TL |
240 | ceph_assert(idx > m_lower_bound); |
241 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
242 | perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
243 | if (!(data.type & PERFCOUNTER_TIME)) | |
244 | return; | |
245 | if (data.type & PERFCOUNTER_LONGRUNAVG) { | |
31f18b77 FG |
246 | data.avgcount++; |
247 | data.u64 += amt.to_nsec(); | |
248 | data.avgcount2++; | |
7c673cae | 249 | } else { |
31f18b77 | 250 | data.u64 += amt.to_nsec(); |
7c673cae FG |
251 | } |
252 | } | |
253 | ||
11fdf7f2 | 254 | void PerfCounters::tinc(int idx, ceph::timespan amt) |
7c673cae | 255 | { |
11fdf7f2 | 256 | #ifndef WITH_SEASTAR |
7c673cae FG |
257 | if (!m_cct->_conf->perf) |
258 | return; | |
11fdf7f2 | 259 | #endif |
7c673cae | 260 | |
11fdf7f2 TL |
261 | ceph_assert(idx > m_lower_bound); |
262 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
263 | perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
264 | if (!(data.type & PERFCOUNTER_TIME)) | |
265 | return; | |
266 | if (data.type & PERFCOUNTER_LONGRUNAVG) { | |
31f18b77 FG |
267 | data.avgcount++; |
268 | data.u64 += amt.count(); | |
269 | data.avgcount2++; | |
7c673cae | 270 | } else { |
31f18b77 | 271 | data.u64 += amt.count(); |
7c673cae FG |
272 | } |
273 | } | |
274 | ||
275 | void PerfCounters::tset(int idx, utime_t amt) | |
276 | { | |
11fdf7f2 | 277 | #ifndef WITH_SEASTAR |
7c673cae FG |
278 | if (!m_cct->_conf->perf) |
279 | return; | |
11fdf7f2 | 280 | #endif |
7c673cae | 281 | |
11fdf7f2 TL |
282 | ceph_assert(idx > m_lower_bound); |
283 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
284 | perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
285 | if (!(data.type & PERFCOUNTER_TIME)) | |
286 | return; | |
31f18b77 | 287 | data.u64 = amt.to_nsec(); |
7c673cae FG |
288 | if (data.type & PERFCOUNTER_LONGRUNAVG) |
289 | ceph_abort(); | |
290 | } | |
291 | ||
292 | utime_t PerfCounters::tget(int idx) const | |
293 | { | |
11fdf7f2 | 294 | #ifndef WITH_SEASTAR |
7c673cae FG |
295 | if (!m_cct->_conf->perf) |
296 | return utime_t(); | |
11fdf7f2 | 297 | #endif |
7c673cae | 298 | |
11fdf7f2 TL |
299 | ceph_assert(idx > m_lower_bound); |
300 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
301 | const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
302 | if (!(data.type & PERFCOUNTER_TIME)) | |
303 | return utime_t(); | |
31f18b77 | 304 | uint64_t v = data.u64; |
7c673cae FG |
305 | return utime_t(v / 1000000000ull, v % 1000000000ull); |
306 | } | |
307 | ||
308 | void PerfCounters::hinc(int idx, int64_t x, int64_t y) | |
309 | { | |
11fdf7f2 | 310 | #ifndef WITH_SEASTAR |
7c673cae FG |
311 | if (!m_cct->_conf->perf) |
312 | return; | |
11fdf7f2 | 313 | #endif |
7c673cae | 314 | |
11fdf7f2 TL |
315 | ceph_assert(idx > m_lower_bound); |
316 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
317 | |
318 | perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); | |
11fdf7f2 TL |
319 | ceph_assert(data.type == (PERFCOUNTER_HISTOGRAM | PERFCOUNTER_COUNTER | PERFCOUNTER_U64)); |
320 | ceph_assert(data.histogram); | |
7c673cae FG |
321 | |
322 | data.histogram->inc(x, y); | |
323 | } | |
324 | ||
11fdf7f2 | 325 | pair<uint64_t, uint64_t> PerfCounters::get_tavg_ns(int idx) const |
7c673cae | 326 | { |
11fdf7f2 | 327 | #ifndef WITH_SEASTAR |
7c673cae FG |
328 | if (!m_cct->_conf->perf) |
329 | return make_pair(0, 0); | |
11fdf7f2 | 330 | #endif |
7c673cae | 331 | |
11fdf7f2 TL |
332 | ceph_assert(idx > m_lower_bound); |
333 | ceph_assert(idx < m_upper_bound); | |
7c673cae FG |
334 | const perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]); |
335 | if (!(data.type & PERFCOUNTER_TIME)) | |
336 | return make_pair(0, 0); | |
337 | if (!(data.type & PERFCOUNTER_LONGRUNAVG)) | |
338 | return make_pair(0, 0); | |
339 | pair<uint64_t,uint64_t> a = data.read_avg(); | |
11fdf7f2 | 340 | return make_pair(a.second, a.first); |
7c673cae FG |
341 | } |
342 | ||
343 | void PerfCounters::reset() | |
344 | { | |
345 | perf_counter_data_vec_t::iterator d = m_data.begin(); | |
346 | perf_counter_data_vec_t::iterator d_end = m_data.end(); | |
347 | ||
348 | while (d != d_end) { | |
349 | d->reset(); | |
350 | ++d; | |
351 | } | |
352 | } | |
353 | ||
354 | void PerfCounters::dump_formatted_generic(Formatter *f, bool schema, | |
eafe8130 | 355 | bool histograms, const std::string &counter) const |
7c673cae FG |
356 | { |
357 | f->open_object_section(m_name.c_str()); | |
358 | ||
359 | for (perf_counter_data_vec_t::const_iterator d = m_data.begin(); | |
360 | d != m_data.end(); ++d) { | |
361 | if (!counter.empty() && counter != d->name) { | |
362 | // Optionally filter on counter name | |
363 | continue; | |
364 | } | |
365 | ||
366 | // Switch between normal and histogram view | |
367 | bool is_histogram = (d->type & PERFCOUNTER_HISTOGRAM) != 0; | |
368 | if (is_histogram != histograms) { | |
369 | continue; | |
370 | } | |
371 | ||
372 | if (schema) { | |
373 | f->open_object_section(d->name); | |
31f18b77 FG |
374 | // we probably should not have exposed this raw field (with bit |
375 | // values), but existing plugins rely on it so we're stuck with | |
376 | // it. | |
7c673cae FG |
377 | f->dump_int("type", d->type); |
378 | ||
31f18b77 FG |
379 | if (d->type & PERFCOUNTER_COUNTER) { |
380 | f->dump_string("metric_type", "counter"); | |
381 | } else { | |
382 | f->dump_string("metric_type", "gauge"); | |
383 | } | |
384 | ||
385 | if (d->type & PERFCOUNTER_LONGRUNAVG) { | |
386 | if (d->type & PERFCOUNTER_TIME) { | |
387 | f->dump_string("value_type", "real-integer-pair"); | |
388 | } else { | |
389 | f->dump_string("value_type", "integer-integer-pair"); | |
390 | } | |
391 | } else if (d->type & PERFCOUNTER_HISTOGRAM) { | |
392 | if (d->type & PERFCOUNTER_TIME) { | |
393 | f->dump_string("value_type", "real-2d-histogram"); | |
394 | } else { | |
395 | f->dump_string("value_type", "integer-2d-histogram"); | |
396 | } | |
7c673cae | 397 | } else { |
31f18b77 FG |
398 | if (d->type & PERFCOUNTER_TIME) { |
399 | f->dump_string("value_type", "real"); | |
400 | } else { | |
401 | f->dump_string("value_type", "integer"); | |
402 | } | |
7c673cae FG |
403 | } |
404 | ||
31f18b77 | 405 | f->dump_string("description", d->description ? d->description : ""); |
7c673cae FG |
406 | if (d->nick != NULL) { |
407 | f->dump_string("nick", d->nick); | |
408 | } else { | |
409 | f->dump_string("nick", ""); | |
410 | } | |
3efd9988 | 411 | f->dump_int("priority", get_adjusted_priority(d->prio)); |
1adf2230 | 412 | |
11fdf7f2 | 413 | if (d->unit == UNIT_NONE) { |
1adf2230 | 414 | f->dump_string("units", "none"); |
11fdf7f2 | 415 | } else if (d->unit == UNIT_BYTES) { |
1adf2230 AA |
416 | f->dump_string("units", "bytes"); |
417 | } | |
7c673cae FG |
418 | f->close_section(); |
419 | } else { | |
420 | if (d->type & PERFCOUNTER_LONGRUNAVG) { | |
421 | f->open_object_section(d->name); | |
422 | pair<uint64_t,uint64_t> a = d->read_avg(); | |
423 | if (d->type & PERFCOUNTER_U64) { | |
424 | f->dump_unsigned("avgcount", a.second); | |
425 | f->dump_unsigned("sum", a.first); | |
426 | } else if (d->type & PERFCOUNTER_TIME) { | |
427 | f->dump_unsigned("avgcount", a.second); | |
428 | f->dump_format_unquoted("sum", "%" PRId64 ".%09" PRId64, | |
429 | a.first / 1000000000ull, | |
430 | a.first % 1000000000ull); | |
31f18b77 FG |
431 | uint64_t count = a.second; |
432 | uint64_t sum_ns = a.first; | |
433 | if (count) { | |
434 | uint64_t avg_ns = sum_ns / count; | |
435 | f->dump_format_unquoted("avgtime", "%" PRId64 ".%09" PRId64, | |
436 | avg_ns / 1000000000ull, | |
437 | avg_ns % 1000000000ull); | |
438 | } else { | |
439 | f->dump_format_unquoted("avgtime", "%" PRId64 ".%09" PRId64, 0, 0); | |
440 | } | |
7c673cae FG |
441 | } else { |
442 | ceph_abort(); | |
443 | } | |
444 | f->close_section(); | |
445 | } else if (d->type & PERFCOUNTER_HISTOGRAM) { | |
11fdf7f2 TL |
446 | ceph_assert(d->type == (PERFCOUNTER_HISTOGRAM | PERFCOUNTER_COUNTER | PERFCOUNTER_U64)); |
447 | ceph_assert(d->histogram); | |
7c673cae FG |
448 | f->open_object_section(d->name); |
449 | d->histogram->dump_formatted(f); | |
450 | f->close_section(); | |
451 | } else { | |
31f18b77 | 452 | uint64_t v = d->u64; |
7c673cae FG |
453 | if (d->type & PERFCOUNTER_U64) { |
454 | f->dump_unsigned(d->name, v); | |
455 | } else if (d->type & PERFCOUNTER_TIME) { | |
456 | f->dump_format_unquoted(d->name, "%" PRId64 ".%09" PRId64, | |
457 | v / 1000000000ull, | |
458 | v % 1000000000ull); | |
459 | } else { | |
460 | ceph_abort(); | |
461 | } | |
462 | } | |
463 | } | |
464 | } | |
465 | f->close_section(); | |
466 | } | |
467 | ||
468 | const std::string &PerfCounters::get_name() const | |
469 | { | |
470 | return m_name; | |
471 | } | |
472 | ||
473 | PerfCounters::PerfCounters(CephContext *cct, const std::string &name, | |
474 | int lower_bound, int upper_bound) | |
475 | : m_cct(cct), | |
476 | m_lower_bound(lower_bound), | |
477 | m_upper_bound(upper_bound), | |
11fdf7f2 | 478 | m_name(name) |
9f95a23c | 479 | #if !defined(WITH_SEASTAR) || defined(WITH_ALIEN) |
11fdf7f2 | 480 | , |
7c673cae | 481 | m_lock_name(std::string("PerfCounters::") + name.c_str()), |
11fdf7f2 TL |
482 | m_lock(ceph::make_mutex(m_lock_name)) |
483 | #endif | |
7c673cae FG |
484 | { |
485 | m_data.resize(upper_bound - lower_bound - 1); | |
486 | } | |
487 | ||
488 | PerfCountersBuilder::PerfCountersBuilder(CephContext *cct, const std::string &name, | |
489 | int first, int last) | |
490 | : m_perf_counters(new PerfCounters(cct, name, first, last)) | |
491 | { | |
492 | } | |
493 | ||
494 | PerfCountersBuilder::~PerfCountersBuilder() | |
495 | { | |
496 | if (m_perf_counters) | |
497 | delete m_perf_counters; | |
498 | m_perf_counters = NULL; | |
499 | } | |
500 | ||
501 | void PerfCountersBuilder::add_u64_counter( | |
502 | int idx, const char *name, | |
1adf2230 | 503 | const char *description, const char *nick, int prio, int unit) |
7c673cae FG |
504 | { |
505 | add_impl(idx, name, description, nick, prio, | |
1adf2230 | 506 | PERFCOUNTER_U64 | PERFCOUNTER_COUNTER, unit); |
7c673cae FG |
507 | } |
508 | ||
509 | void PerfCountersBuilder::add_u64( | |
510 | int idx, const char *name, | |
1adf2230 | 511 | const char *description, const char *nick, int prio, int unit) |
7c673cae | 512 | { |
1adf2230 | 513 | add_impl(idx, name, description, nick, prio, PERFCOUNTER_U64, unit); |
7c673cae FG |
514 | } |
515 | ||
516 | void PerfCountersBuilder::add_u64_avg( | |
517 | int idx, const char *name, | |
1adf2230 | 518 | const char *description, const char *nick, int prio, int unit) |
7c673cae FG |
519 | { |
520 | add_impl(idx, name, description, nick, prio, | |
1adf2230 | 521 | PERFCOUNTER_U64 | PERFCOUNTER_LONGRUNAVG, unit); |
7c673cae FG |
522 | } |
523 | ||
524 | void PerfCountersBuilder::add_time( | |
525 | int idx, const char *name, | |
526 | const char *description, const char *nick, int prio) | |
527 | { | |
528 | add_impl(idx, name, description, nick, prio, PERFCOUNTER_TIME); | |
529 | } | |
530 | ||
531 | void PerfCountersBuilder::add_time_avg( | |
532 | int idx, const char *name, | |
533 | const char *description, const char *nick, int prio) | |
534 | { | |
535 | add_impl(idx, name, description, nick, prio, | |
536 | PERFCOUNTER_TIME | PERFCOUNTER_LONGRUNAVG); | |
537 | } | |
538 | ||
31f18b77 | 539 | void PerfCountersBuilder::add_u64_counter_histogram( |
7c673cae FG |
540 | int idx, const char *name, |
541 | PerfHistogramCommon::axis_config_d x_axis_config, | |
542 | PerfHistogramCommon::axis_config_d y_axis_config, | |
1adf2230 | 543 | const char *description, const char *nick, int prio, int unit) |
7c673cae FG |
544 | { |
545 | add_impl(idx, name, description, nick, prio, | |
1adf2230 | 546 | PERFCOUNTER_U64 | PERFCOUNTER_HISTOGRAM | PERFCOUNTER_COUNTER, unit, |
7c673cae FG |
547 | unique_ptr<PerfHistogram<>>{new PerfHistogram<>{x_axis_config, y_axis_config}}); |
548 | } | |
549 | ||
550 | void PerfCountersBuilder::add_impl( | |
551 | int idx, const char *name, | |
1adf2230 | 552 | const char *description, const char *nick, int prio, int ty, int unit, |
7c673cae FG |
553 | unique_ptr<PerfHistogram<>> histogram) |
554 | { | |
11fdf7f2 TL |
555 | ceph_assert(idx > m_perf_counters->m_lower_bound); |
556 | ceph_assert(idx < m_perf_counters->m_upper_bound); | |
7c673cae FG |
557 | PerfCounters::perf_counter_data_vec_t &vec(m_perf_counters->m_data); |
558 | PerfCounters::perf_counter_data_any_d | |
559 | &data(vec[idx - m_perf_counters->m_lower_bound - 1]); | |
11fdf7f2 | 560 | ceph_assert(data.type == PERFCOUNTER_NONE); |
7c673cae FG |
561 | data.name = name; |
562 | data.description = description; | |
563 | // nick must be <= 4 chars | |
564 | if (nick) { | |
11fdf7f2 | 565 | ceph_assert(strlen(nick) <= 4); |
7c673cae FG |
566 | } |
567 | data.nick = nick; | |
3efd9988 | 568 | data.prio = prio ? prio : prio_default; |
7c673cae | 569 | data.type = (enum perfcounter_type_d)ty; |
1adf2230 | 570 | data.unit = (enum unit_t) unit; |
7c673cae FG |
571 | data.histogram = std::move(histogram); |
572 | } | |
573 | ||
574 | PerfCounters *PerfCountersBuilder::create_perf_counters() | |
575 | { | |
576 | PerfCounters::perf_counter_data_vec_t::const_iterator d = m_perf_counters->m_data.begin(); | |
577 | PerfCounters::perf_counter_data_vec_t::const_iterator d_end = m_perf_counters->m_data.end(); | |
31f18b77 | 578 | for (; d != d_end; ++d) { |
11fdf7f2 TL |
579 | ceph_assert(d->type != PERFCOUNTER_NONE); |
580 | ceph_assert(d->type & (PERFCOUNTER_U64 | PERFCOUNTER_TIME)); | |
31f18b77 | 581 | } |
7c673cae FG |
582 | |
583 | PerfCounters *ret = m_perf_counters; | |
584 | m_perf_counters = NULL; | |
585 | return ret; | |
586 | } | |
587 | ||
9f95a23c | 588 | } |