mirror of
https://github.com/ceph/ceph
synced 2025-02-24 03:27:10 +00:00
mgr/ServiceMap: adjust 'ceph -s' summary
- 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>
This commit is contained in:
parent
afc33758e0
commit
ab0d8f2ae9
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user