diff --git a/src/server/main_service.cc b/src/server/main_service.cc
index 259b8c2a9..6b9d0ea80 100644
--- a/src/server/main_service.cc
+++ b/src/server/main_service.cc
@@ -549,6 +549,95 @@ void TxTable(const http::QueryArgs& args, HttpContext* send) {
send->Invoke(std::move(resp));
}
+void ClusterHtmlPage(const http::QueryArgs& args, HttpContext* send, ClusterFamily* cluster) {
+ http::StringResponse resp = http::MakeStringResponse(h2::status::ok);
+ resp.body() = R"(
+
+
+
+
+
+ \n";
+ resp.body() += "
Master
\n";
+ print_kv("ID", shard.master.id);
+ print_kv("IP", shard.master.ip);
+ print_kv("Port", absl::StrCat(shard.master.port));
+
+ resp.body() += "
Replicas
\n";
+ if (shard.replicas.empty()) {
+ resp.body() += "
None
\n";
+ } else {
+ for (const auto& replica : shard.replicas) {
+ resp.body() += "
Replica
\n";
+ print_kv("ID", replica.id);
+ print_kv("IP", replica.ip);
+ print_kv("Port", absl::StrCat(replica.port));
+ }
+ }
+
+ resp.body() += "
Slots
\n";
+ for (const auto& slot : shard.slot_ranges) {
+ resp.body() +=
+ absl::StrCat("
[", slot.start,
+ "-", slot.end, "]
");
+ }
+
+ resp.body() += "
\n";
+ }
+ }
+ }
+
+ resp.body() += " \n\n";
+ send->Invoke(std::move(resp));
+}
+
enum class ExecEvalState {
NONE = 0,
ALL = 1,
@@ -2201,6 +2290,9 @@ void Service::ConfigureHttpHandlers(util::HttpListenerBase* base, bool is_privil
server_family_.ConfigureMetrics(base);
base->RegisterCb("/txz", TxTable);
base->RegisterCb("/topkeys", Topkeys);
+ base->RegisterCb("/clusterz", [this](const http::QueryArgs& args, HttpContext* send) {
+ return ClusterHtmlPage(args, send, &cluster_family_);
+ });
}
void Service::OnClose(facade::ConnectionContext* cntx) {