| 1141 | } |
| 1142 | |
| 1143 | PyObject* ActivePyModules::get_perf_schema_python( |
| 1144 | const std::string& svc_type, |
| 1145 | const std::string& svc_id) |
| 1146 | { |
| 1147 | without_gil_t no_gil; |
| 1148 | std::lock_guard l(lock); |
| 1149 | |
| 1150 | DaemonStateCollection daemons; |
| 1151 | |
| 1152 | if (svc_type == "") { |
| 1153 | daemons = daemon_state.get_all(); |
| 1154 | } else if (svc_id.empty()) { |
| 1155 | daemons = daemon_state.get_by_service(svc_type); |
| 1156 | } else { |
| 1157 | auto key = DaemonKey{svc_type, svc_id}; |
| 1158 | // so that the below can be a loop in all cases |
| 1159 | auto got = daemon_state.get(key); |
| 1160 | if (got != nullptr) { |
| 1161 | daemons[key] = got; |
| 1162 | } |
| 1163 | } |
| 1164 | |
| 1165 | auto f = with_gil(no_gil, [&] { return PyFormatter(); }); |
| 1166 | |
| 1167 | auto dump_sub_counter_information = [](PyFormatter *f, PerfCounterType type) { |
| 1168 | // Labels can also have "." in them, eg (notice, client.4620): |
| 1169 | // "mds_client_metrics-cephfs^@client^@client.4620^@rank^@0^@.avg_metadata_latency" |
| 1170 | // Hence search for the last occurence of "." to get sub counter name |
| 1171 | size_t pos = type.path.rfind('.'); |
| 1172 | std::string sub_counter_name = type.path.substr(pos + 1, type.path.length()); |
| 1173 | Formatter::ObjectSection counter_section(*f, sub_counter_name); |
| 1174 | f->create_unique("description", type.description); |
| 1175 | if (!type.nick.empty()) { |
| 1176 | f->dump_string("nick", type.nick); |
| 1177 | } |
| 1178 | f->dump_unsigned("type", type.type); |
| 1179 | f->dump_unsigned("priority", type.priority); |
| 1180 | f->dump_unsigned("units", type.unit); |
| 1181 | }; |
| 1182 | |
| 1183 | auto dump_counter_with_labels = [&dump_sub_counter_information]( |
| 1184 | PyFormatter *f, auto key_labels, |
| 1185 | auto type) { |
| 1186 | f->open_object_section(""); // counter should be enclosed by array |
| 1187 | |
| 1188 | for (Formatter::ObjectSection labels_section{*f, "labels"}; |
| 1189 | const auto &label : key_labels) { |
| 1190 | f->dump_string(label.first, label.second); |
| 1191 | } |
| 1192 | |
| 1193 | f->open_object_section("counters"); |
| 1194 | dump_sub_counter_information(f, type); |
| 1195 | }; |
| 1196 | |
| 1197 | |
| 1198 | if (!daemons.empty()) { |
| 1199 | for (auto &[key, state] : daemons) { |
| 1200 | std::lock_guard l(state->lock); |
no test coverage detected