]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
exporter: export labeled perf-counters as prometheus metrics 50369/head
authoravanthakkar <avanjohn@gmail.com>
Fri, 3 Mar 2023 13:20:00 +0000 (18:50 +0530)
committerAvan Thakkar <athakkar@redhat.com>
Thu, 23 Mar 2023 14:37:00 +0000 (20:07 +0530)
Fixes: https://tracker.ceph.com/issues/59063
Signed-off-by: Avan Thakkar <athakkar@redhat.com>
src/common/options/ceph-exporter.yaml.in
src/exporter/DaemonMetricCollector.cc

index 798a185e96bcc1ec6e205d8a66e196071bf570e1..269dccd68cb95979fe42f9c56dcabe072313e1cc 100644 (file)
@@ -52,3 +52,15 @@ options:
   - ceph-exporter
   flags:
   - runtime
+- name: exporter_get_labeled_counters
+  type: bool
+  level: advanced
+  desc: If true will fetch and export labeled performance counters
+  long_desc: Ceph perf counters now support labels to provide fine-grained
+    stats using ``counter dump`` command and exporter can fetch these counters
+    and add the labels in Prometheus format.
+  default: true
+  services:
+  - ceph-exporter
+  flags:
+  - runtime
index a8fef46548e92aa05bab4d0293beb3015b59fa2d..779519b53e9b9dce0a83e361c070675b2b51ae74 100644 (file)
@@ -134,6 +134,7 @@ void DaemonMetricCollector::dump_asok_metrics() {
     }
     json_object dump = boost::json::parse(perf_dump_response).as_object();
     json_object schema = boost::json::parse(perf_schema_response).as_object();
+    auto prio_limit = g_conf().get_val<int64_t>("exporter_prio_limit");
     for (auto &perf : schema) {
       std::string perf_group = {perf.key().begin(), perf.key().end()};
       json_object perf_group_object = perf.value().as_object();
@@ -141,14 +142,12 @@ void DaemonMetricCollector::dump_asok_metrics() {
         std::string perf_name = {perf_counter.key().begin(),
                                  perf_counter.key().end()};
         json_object perf_info = perf_counter.value().as_object();
-        auto prio_limit = g_conf().get_val<int64_t>("exporter_prio_limit");
         if (perf_info["priority"].as_int64() < prio_limit) {
           continue;
         }
         std::string name = "ceph_" + perf_group + "_" + perf_name;
         std::replace_if(name.begin(), name.end(), is_hyphen, '_');
 
-        // FIXME: test this, based on mgr_module perfpath_to_path_labels
         auto labels_and_name = get_labels_and_metric_name(daemon_name, name);
         labels_t labels = labels_and_name.first;
         name = labels_and_name.second;
@@ -157,6 +156,52 @@ void DaemonMetricCollector::dump_asok_metrics() {
         dump_asok_metric(perf_info, perf_values, name, labels);
       }
     }
+    // fetch labeled perf counters if config is set to true
+    bool labeledperf = g_conf().get_val<bool>("exporter_get_labeled_counters");
+    if (labeledperf) {
+       std::string counter_dump_response =
+        asok_request(sock_client, "counter dump", daemon_name);
+      if (counter_dump_response.size() == 0) {
+          failures++;
+          continue;
+      }
+      std::string counter_schema_response =
+          asok_request(sock_client, "counter schema", daemon_name);
+      if (counter_schema_response.size() == 0) {
+        failures++;
+        continue;
+      }
+
+      json_object counter_dump = boost::json::parse(counter_dump_response).as_object();
+      json_object counter_schema = boost::json::parse(counter_schema_response).as_object();
+
+      for (auto &labeled_perf : counter_schema) {
+        std::string labeled_perf_group = {labeled_perf.key().begin(), labeled_perf.key().end()};
+        json_object labeled_perf_group_object = labeled_perf.value().as_object();
+        auto counters = labeled_perf_group_object["counters"].as_object();
+        auto counters_labels = labeled_perf_group_object["labels"].as_object();
+        auto labeled_perf_group_counters = counter_dump[labeled_perf_group].as_object()["counters"].as_object();
+        labels_t labels;
+
+        for(auto &label: counters_labels) {
+          std::string label_key = {label.key().begin(), label.key().end()};
+          labels[label_key] = quote(label.value().as_string().c_str());
+        }
+        labels["ceph_daemon"] = quote(daemon_name);
+        for (auto &counter : counters) {
+          json_object counter_group = counter.value().as_object();
+          if (counter_group["priority"].as_int64() < prio_limit) {
+            continue;        
+          }
+          std::string counter_name_init =  {counter.key().begin(), counter.key().end()};
+          std::string counter_name = "ceph_" + labeled_perf_group + "_" + counter_name_init;
+          std::replace_if(counter_name.begin(), counter_name.end(), is_hyphen, '_');
+
+          auto perf_values = labeled_perf_group_counters.at(counter_name_init);
+          dump_asok_metric(counter_group, perf_values, counter_name, labels);
+      }
+    }
+  }
   }
   dout(10) << "Perf counters retrieved for " << clients.size() - failures << "/"
            << clients.size() << " daemons." << dendl;