1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "common/debug.h"
5 #include "common/errno.h"
7 #include "mgr/MetricCollector.h"
8 #include "mgr/OSDPerfMetricTypes.h"
10 #define dout_context g_ceph_context
11 #define dout_subsys ceph_subsys_mgr
13 #define dout_prefix *_dout << "mgr.metric_collector " << __func__ << ": "
15 template <typename Query
, typename Limit
, typename Key
, typename Report
>
16 MetricCollector
<Query
, Limit
, Key
, Report
>::MetricCollector(MetricListener
&listener
)
21 template <typename Query
, typename Limit
, typename Key
, typename Report
>
22 MetricQueryID MetricCollector
<Query
, Limit
, Key
, Report
>::add_query(
24 const std::optional
<Limit
> &limit
) {
25 dout(20) << "query=" << query
<< ", limit=" << limit
<< dendl
;
30 std::lock_guard
locker(lock
);
32 query_id
= next_query_id
++;
33 auto it
= queries
.find(query
);
34 if (it
== queries
.end()) {
35 it
= queries
.emplace(query
, std::map
<MetricQueryID
, OptionalLimit
>{}).first
;
37 } else if (is_limited(it
->second
)) {
41 it
->second
.emplace(query_id
, limit
);
42 counters
.emplace(query_id
, std::map
<Key
, PerformanceCounters
>{});
45 dout(10) << query
<< " " << (limit
? stringify(*limit
) : "unlimited")
46 << " query_id=" << query_id
<< dendl
;
49 listener
.handle_query_updated();
55 template <typename Query
, typename Limit
, typename Key
, typename Report
>
56 int MetricCollector
<Query
, Limit
, Key
, Report
>::remove_query(MetricQueryID query_id
) {
57 dout(20) << "query_id=" << query_id
<< dendl
;
62 std::lock_guard
locker(lock
);
64 for (auto it
= queries
.begin() ; it
!= queries
.end();) {
65 auto iter
= it
->second
.find(query_id
);
66 if (iter
== it
->second
.end()) {
71 it
->second
.erase(iter
);
72 if (it
->second
.empty()) {
73 it
= queries
.erase(it
);
75 } else if (is_limited(it
->second
)) {
82 counters
.erase(query_id
);
86 dout(10) << query_id
<< " not found" << dendl
;
90 dout(10) << query_id
<< dendl
;
93 listener
.handle_query_updated();
99 template <typename Query
, typename Limit
, typename Key
, typename Report
>
100 void MetricCollector
<Query
, Limit
, Key
, Report
>::remove_all_queries() {
105 std::lock_guard
locker(lock
);
107 notify
= !queries
.empty();
112 listener
.handle_query_updated();
116 template <typename Query
, typename Limit
, typename Key
, typename Report
>
117 int MetricCollector
<Query
, Limit
, Key
, Report
>::get_counters(
118 MetricQueryID query_id
, std::map
<Key
, PerformanceCounters
> *c
) {
121 std::lock_guard
locker(lock
);
123 auto it
= counters
.find(query_id
);
124 if (it
== counters
.end()) {
125 dout(10) << "counters for " << query_id
<< " not found" << dendl
;
129 *c
= std::move(it
->second
);
135 template <typename Query
, typename Limit
, typename Key
, typename Report
>
136 void MetricCollector
<Query
, Limit
, Key
, Report
>::process_reports_generic(
137 const std::map
<Query
, Report
> &reports
, UpdateCallback callback
) {
138 ceph_assert(ceph_mutex_is_locked(lock
));
140 if (reports
.empty()) {
144 for (auto& [query
, report
] : reports
) {
145 dout(10) << "report for " << query
<< " query: "
146 << report
.group_packed_performance_counters
.size() << " records"
149 for (auto& [key
, bl
] : report
.group_packed_performance_counters
) {
150 auto bl_it
= bl
.cbegin();
152 for (auto& p
: queries
[query
]) {
153 auto &key_counters
= counters
[p
.first
][key
];
154 if (key_counters
.empty()) {
155 key_counters
.resize(query
.performance_counter_descriptors
.size(),
160 auto desc_it
= report
.performance_counter_descriptors
.begin();
161 for (size_t i
= 0; i
< query
.performance_counter_descriptors
.size(); i
++) {
162 if (desc_it
== report
.performance_counter_descriptors
.end()) {
165 if (*desc_it
!= query
.performance_counter_descriptors
[i
]) {
168 PerformanceCounter c
;
169 desc_it
->unpack_counter(bl_it
, &c
);
170 dout(20) << "counter " << key
<< " " << *desc_it
<< ": " << c
<< dendl
;
172 for (auto& p
: queries
[query
]) {
173 auto &key_counters
= counters
[p
.first
][key
];
174 callback(&key_counters
[i
], c
);
183 MetricCollector
<OSDPerfMetricQuery
, OSDPerfMetricLimit
, OSDPerfMetricKey
, OSDPerfMetricReport
>;