void Monitor::get_cluster_status(stringstream &ss, Formatter *f)
{
  if (f)
    f->open_object_section("status");

  if (f) {
    f->dump_stream("fsid") << monmap->get_fsid();
    if (osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) {
      get_health_status(false, f, nullptr);
    } else {
      list<string> health_str;
      get_health(health_str, nullptr, f);
    }
    f->dump_unsigned("election_epoch", get_epoch());
    {
      f->open_array_section("quorum");
      for (set<int>::iterator p = quorum.begin(); p != quorum.end(); ++p)
	f->dump_int("rank", *p);
      f->close_section();
      f->open_array_section("quorum_names");
      for (set<int>::iterator p = quorum.begin(); p != quorum.end(); ++p)
	f->dump_string("id", monmap->get_name(*p));
      f->close_section();
    }
    f->open_object_section("monmap");
    monmap->dump(f);
    f->close_section();
    f->open_object_section("osdmap");
    osdmon()->osdmap.print_summary(f, cout, string(12, ' '));
    f->close_section();
    f->open_object_section("pgmap");
    pgservice->print_summary(f, NULL);
    f->close_section();
    f->open_object_section("fsmap");
    mdsmon()->get_fsmap().print_summary(f, NULL);
    f->close_section();
    f->open_object_section("mgrmap");
    mgrmon()->get_map().print_summary(f, nullptr);
    f->close_section();

    f->dump_object("servicemap", mgrstatmon()->get_service_map());
    f->close_section();
  } else {
    ss << "  cluster:\n";
    ss << "    id:     " << monmap->get_fsid() << "\n";

    string health;
    if (osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) {
      get_health_status(false, nullptr, &health,
			"\n            ", "\n            ");
    } else {
      list<string> ls;
      get_health(ls, NULL, f);
      health = joinify(ls.begin(), ls.end(),
		       string("\n            "));
    }
    ss << "    health: " << health << "\n";

    ss << "\n \n  services:\n";
    {
      size_t maxlen = 3;
      auto& service_map = mgrstatmon()->get_service_map();
      for (auto& p : service_map.services) {
	maxlen = std::max(maxlen, p.first.size());
      }
      string spacing(maxlen - 3, ' ');
      const auto quorum_names = get_quorum_names();
      const auto mon_count = monmap->mon_info.size();
      ss << "    mon: " << spacing << mon_count << " daemons, quorum "
	 << quorum_names;
      if (quorum_names.size() != mon_count) {
	std::list<std::string> out_of_q;
	for (size_t i = 0; i < monmap->ranks.size(); ++i) {
	  if (quorum.count(i) == 0) {
	    out_of_q.push_back(monmap->ranks[i]);
	  }
	}
	ss << ", out of quorum: " << joinify(out_of_q.begin(),
					     out_of_q.end(), std::string(", "));
      }
      ss << "\n";
      if (mgrmon()->in_use()) {
	ss << "    mgr: " << spacing;
	mgrmon()->get_map().print_summary(nullptr, &ss);
	ss << "\n";
      }
      if (mdsmon()->get_fsmap().filesystem_count() > 0) {
	ss << "    mds: " << spacing << mdsmon()->get_fsmap() << "\n";
      }
      ss << "    osd: " << spacing;
      osdmon()->osdmap.print_summary(NULL, ss, string(maxlen + 6, ' '));
      ss << "\n";
      for (auto& p : service_map.services) {
	ss << "    " << p.first << ": " << string(maxlen - p.first.size(), ' ')
	   << p.second.get_summary() << "\n";
      }
    }

    ss << "\n \n  data:\n";
    pgservice->print_summary(NULL, &ss);
    ss << "\n ";
  }
}