]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/ServiceMap: adjust 'ceph -s' summary
authorSage Weil <sage@newdream.net>
Fri, 19 Mar 2021 12:21:18 +0000 (08:21 -0400)
committerSage Weil <sage@newdream.net>
Sat, 20 Mar 2021 13:23:11 +0000 (08:23 -0500)
- Do not list individual daemon ids as this won't scale for larger
  clusters
- Do not contemplate multile daemons of the same type that register with
  different "daemon_type" -- not until we actually have any that do that.
- Present counts by various groupings: distinct hosts and rgw zones to
  start.

  services:
    mon:           1 daemons, quorum a (age 4m)
    mgr:           x(active, since 3m)
    osd:           1 osds: 1 up (since 3m), 1 in (since 3m)
    cephfs-mirror: 1 daemon active (1 hosts)
    rbd-mirror:    2 daemons active (1 hosts)
    rgw:           2 daemons active (1 hosts, 1 zones)

Signed-off-by: Sage Weil <sage@newdream.net>
(cherry picked from commit ab0d8f2ae9f551e15a4c7bacbf69161e91263785)

src/mgr/ServiceMap.cc
src/test/librados/service.cc

index 4babb81f224c026ab0740d6948313253921ea1a6..b6f8ad97c86d103be1db55a58169244bcf1ec3b2 100644 (file)
@@ -78,60 +78,48 @@ std::string ServiceMap::Service::get_summary() const
     return "no daemons active";
   }
 
-  std::ostringstream ss;
-
-  // The format two pairs in metadata:
-  //   "daemon_type"   : "${TYPE}"
-  //   "daemon_prefix" : "${PREFIX}"
+  // If "daemon_type" is present, this will be used in place of "daemon" when
+  // reporting the count (e.g., "${N} daemons").
   //
-  // TYPE: will be used to replace the default "daemon(s)"
-  // showed in `ceph -s`. If absent, the "daemon" will be used.
-  // PREFIX: if present the active members will be classified
-  // by the prefix instead of "daemon_name".
+  // We will additional break down the count by various groupings, based
+  // on the following keys:
+  //
+  //   "hostname" -> host(s)
+  //   "zone_id" -> zone(s)
   //
-  // For exmaple for iscsi gateways, it will be something likes:
-  //   "daemon_type"   : "portal"
-  //   "daemon_prefix" : "gateway${N}"
   // The `ceph -s` will be something likes:
-  //    iscsi: 3 portals active (gateway0, gateway1, gateway2)
+  //    iscsi: 3 portals active (3 hosts)
+  //      rgw: 3 gateways active (3 hosts, 1 zone)
 
-  std::map<std::string, std::set<std::string>> prefs;
+  std::map<std::string, std::set<std::string>> groupings;
+  std::string type("daemon");
+  int num = 0;
   for (auto& d : daemons) {
-    // In case the "daemon_type" is absent, use the
-    // default "daemon" type
-    std::string type("daemon");
-    std::string prefix;
-
-    auto t = d.second.metadata.find("daemon_type");
-    if (t != d.second.metadata.end()) {
-      type = d.second.metadata.at("daemon_type");
+    ++num;
+    if (auto p = d.second.metadata.find("daemon_type");
+       p != d.second.metadata.end()) {
+      type = p->second;
     }
-    auto p = d.second.metadata.find("daemon_prefix");
-    if (p != d.second.metadata.end()) {
-      prefix = d.second.metadata.at("daemon_prefix");
-    } else {
-      // In case the "daemon_prefix" is absent, show
-      // the daemon_name instead.
-      prefix = d.first;
+    for (auto k : {make_pair("zone", "zone_id"),
+         make_pair("host", "hostname")}) {
+      auto p = d.second.metadata.find(k.second);
+      if (p != d.second.metadata.end()) {
+       groupings[k.first].insert(p->second);
+      }
     }
-    auto& pref = prefs[type];
-    pref.insert(prefix);
   }
 
-  for (auto &pr : prefs) {
-    if (!ss.str().empty())
-      ss << ", ";
-
-    ss << pr.second.size() << " " << pr.first
-       << (pr.second.size() > 1 ? "s" : "")
-       << " active";
-
-    if (pr.second.size()) {
-      ss << " (";
-      std::copy(std::begin(pr.second), std::end(pr.second),
-                std::experimental::make_ostream_joiner(ss, ", "));
-      ss << ")";
+  std::ostringstream ss;
+  ss << num << " " << type << (num > 1 ? "s" : "") << " active";
+  if (groupings.size()) {
+    ss << " (";
+    for (auto i = groupings.begin(); i != groupings.end(); ++i) {
+      if (i != groupings.begin()) {
+       ss << ", ";
+      }
+      ss << i->second.size() << " " << i->first << (i->second.size() ? "s" : "");
     }
+    ss << ")";
   }
 
   return ss.str();
index 9611b40eb11078012afd8ee876382f13141ae70b..bc8e26efaf4d89aee3204af00728d0a9f71d7dea 100644 (file)
@@ -71,12 +71,16 @@ static void status_format_func(const int i, std::mutex &lock,
                            "daemon_prefix", '\0', "gateway", '\0'));
   } else {
     string prefix = string("gw") + stringify(i % 4);
-    ASSERT_NE(-1, asprintf(&metadata_buf, "%s%c%s%c%s%c%s%c",
+    string zone = string("z") + stringify(i % 3);
+    ASSERT_NE(-1, asprintf(&metadata_buf, "%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s%c",
                            "daemon_type", '\0', "portal", '\0',
-                           "daemon_prefix", '\0', prefix.c_str(), '\0'));
+                           "daemon_prefix", '\0', prefix.c_str(), '\0',
+                          "hostname", '\0', prefix.c_str(), '\0',
+                          "zone_id", '\0', zone.c_str(), '\0'
+               ));
   }
   string name = string("rbd/image") + stringify(i);
-  ASSERT_EQ(0, rados_service_register(cluster, "iscsi", name.c_str(),
+  ASSERT_EQ(0, rados_service_register(cluster, "foo", name.c_str(),
                                      metadata_buf));
 
   std::unique_lock<std::mutex> l(lock);
@@ -140,10 +144,10 @@ TEST(LibRadosService, StatusFormat) {
     ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0,
               &outbuf, &outlen, NULL, NULL));
     std::string out(outbuf, outlen);
+    cout << out << std::endl;
     bool success = false;
-    auto r1 = out.find("5 portals active (gw0, gw1, gw2, gw3, rbd/image1)");
-    auto r2 = out.find("2 daemons active (gateway, rbd/image0");
-    if (std::string::npos != r1 && std::string::npos != r2) {
+    auto r1 = out.find("16 portals active (1 hosts, 3 zones)");
+    if (std::string::npos != r1) {
       success = true;
     }
     rados_buffer_free(outbuf);