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"
9 #include "mgr/MDSPerfMetricTypes.h"
11 #define dout_context g_ceph_context
12 #define dout_subsys ceph_subsys_mgr
14 #define dout_prefix *_dout << "mgr.metric_collector " << __func__ << ": "
16 template <typename Query
, typename Limit
, typename Key
, typename Report
>
17 MetricCollector
<Query
, Limit
, Key
, Report
>::MetricCollector(MetricListener
&listener
)
22 template <typename Query
, typename Limit
, typename Key
, typename Report
>
23 MetricQueryID MetricCollector
<Query
, Limit
, Key
, Report
>::add_query(
25 const std::optional
<Limit
> &limit
) {
26 dout(20) << "query=" << query
<< ", limit=" << limit
<< dendl
;
31 std::lock_guard
locker(lock
);
33 query_id
= next_query_id
++;
34 auto it
= queries
.find(query
);
35 if (it
== queries
.end()) {
36 it
= queries
.emplace(query
, std::map
<MetricQueryID
, OptionalLimit
>{}).first
;
38 } else if (is_limited(it
->second
)) {
42 it
->second
.emplace(query_id
, limit
);
43 counters
.emplace(query_id
, std::map
<Key
, PerformanceCounters
>{});
46 dout(10) << query
<< " " << (limit
? stringify(*limit
) : "unlimited")
47 << " query_id=" << query_id
<< dendl
;
50 listener
.handle_query_updated();
56 template <typename Query
, typename Limit
, typename Key
, typename Report
>
57 int MetricCollector
<Query
, Limit
, Key
, Report
>::remove_query(MetricQueryID query_id
) {
58 dout(20) << "query_id=" << query_id
<< dendl
;
63 std::lock_guard
locker(lock
);
65 for (auto it
= queries
.begin() ; it
!= queries
.end();) {
66 auto iter
= it
->second
.find(query_id
);
67 if (iter
== it
->second
.end()) {
72 it
->second
.erase(iter
);
73 if (it
->second
.empty()) {
74 it
= queries
.erase(it
);
76 } else if (is_limited(it
->second
)) {
83 counters
.erase(query_id
);
87 dout(10) << query_id
<< " not found" << dendl
;
91 dout(10) << query_id
<< dendl
;
94 listener
.handle_query_updated();
100 template <typename Query
, typename Limit
, typename Key
, typename Report
>
101 void MetricCollector
<Query
, Limit
, Key
, Report
>::remove_all_queries() {
106 std::lock_guard
locker(lock
);
108 notify
= !queries
.empty();
113 listener
.handle_query_updated();
117 template <typename Query
, typename Limit
, typename Key
, typename Report
>
118 int MetricCollector
<Query
, Limit
, Key
, Report
>::get_counters_generic(
119 MetricQueryID query_id
, std::map
<Key
, PerformanceCounters
> *c
) {
121 ceph_assert(ceph_mutex_is_locked(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
>;
185 MetricCollector
<MDSPerfMetricQuery
, MDSPerfMetricLimit
, MDSPerfMetricKey
, MDSPerfMetrics
>;