-
Notifications
You must be signed in to change notification settings - Fork 1k
/
master-path-handlers.h
357 lines (297 loc) · 13.9 KB
/
master-path-handlers.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// The following only applies to changes made to this file as part of YugaByte development.
//
// Portions Copyright (c) YugaByte, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations
// under the License.
//
#pragma once
#include <string>
#include <sstream>
#include <vector>
#include "yb/common/wire_protocol.pb.h"
#include "yb/gutil/macros.h"
#include "yb/master/master_fwd.h"
#include "yb/server/webserver.h"
#include "yb/server/monitored_task.h"
#include "yb/util/enums.h"
#include "yb/util/jsonwriter.h"
namespace yb {
class Schema;
namespace master {
static constexpr char kTserverAlive[] = "ALIVE";
static constexpr char kTserverDead[] = "DEAD";
class Master;
struct TabletReplica;
class TSDescriptor;
class TSRegistrationPB;
YB_DEFINE_ENUM(TServersViewType, (kTServersDefaultView)(kTServersClocksView));
// Web page support for the master.
class MasterPathHandlers {
public:
explicit MasterPathHandlers(Master* master)
: master_(master),
output_precision_(6) {
}
~MasterPathHandlers();
const std::string kYBOrange = "#f75821";
const std::string kYBDarkBlue = "#202951";
const std::string kYBLightBlue = "#3eb1cc";
const std::string kYBGray = "#5e647a";
const std::vector<std::string> kYBColorList = {
"#30307F", "#36B8F5",
"#BB43BC", "#43BFC2", "#90948E",
"#1C7180", "#EEA95F", "#3590D9",
"#F0679E", "#707B8E", "#800000",
"#F08080", "#FF8C00", "#7CFC00",
"#D2691E", "#696969", "#FFD700",
"#B8860B", "#006400", "#FF6347"
};
Status Register(Webserver* server);
std::string BytesToHumanReadable (uint64_t bytes);
private:
enum TableType {
kUserTable,
kUserIndex,
kParentTable,
kSystemTable,
kNumTypes,
};
enum CatalogTableColumns {
kKeyspace,
kTableName,
kState,
kMessage,
kUuid,
kYsqlOid,
kParentOid,
kColocationId,
kOnDiskSize,
kHidden,
kNumColumns
};
enum NamespaceColumns {
kNamespaceName,
kNamespaceId,
kNamespaceLanguage,
kNamespaceState,
kNamespaceColocated,
kNumNamespaceColumns
};
struct TabletCounts {
uint32_t user_tablet_leaders = 0;
uint32_t user_tablet_followers = 0;
uint32_t system_tablet_leaders = 0;
uint32_t system_tablet_followers = 0;
// Hidden tablets are not broken down by leader vs. follower or user vs. system. They just count
// the number of tablets peers which are hidden.
uint32_t hidden_tablet_peers = 0;
void operator+=(const TabletCounts& other);
};
// Struct used to store the number of nodes and tablets in an availability zone.
struct ZoneTabletCounts {
TabletCounts tablet_counts;
uint32_t node_count = 1;
uint32_t active_tablets_count;
ZoneTabletCounts() = default;
// Create a ZoneTabletCounts object from the TabletCounts of a TServer (one node).
ZoneTabletCounts(const TabletCounts& tablet_counts, uint32_t active_tablets_count);
void operator+=(const ZoneTabletCounts& other);
typedef std::map<std::string, ZoneTabletCounts> ZoneTree;
typedef std::map<std::string, ZoneTree> RegionTree;
typedef std::map<std::string, RegionTree> CloudTree;
};
struct PlacementClusterTabletCounts {
TabletCounts counts;
uint32_t live_node_count = 0;
uint32_t blacklisted_node_count = 0;
uint32_t dead_node_count = 0;
uint32_t active_tablet_peer_count = 0;
// Tablet replica limits are computed from flag values. If these flag values are unset the
// universe will have no limit. This is represented with std::nullopt.
std::optional<uint64_t> tablet_replica_limit = 0;
};
struct UniverseTabletCounts {
// Keys are placement_uuids.
std::unordered_map<std::string, PlacementClusterTabletCounts> per_placement_cluster_counts;
};
// Map of tserver UUID -> TabletCounts
typedef std::unordered_map<std::string, TabletCounts> TabletCountMap;
UniverseTabletCounts CalculateUniverseTabletCounts(
const TabletCountMap& tablet_count_map,
const std::vector<std::shared_ptr<TSDescriptor>>& descs, const BlacklistSet& blacklist_set,
int hide_dead_node_threshold_mins);
struct ReplicaInfo {
PeerRole role;
TabletId tablet_id;
ReplicaInfo(const PeerRole& role, const TabletId& tablet_id) {
this->role = role;
this->tablet_id = tablet_id;
}
};
// Map of table id -> tablet list for a tserver.
typedef std::unordered_map<std::string, std::vector<ReplicaInfo>> PerTServerTableTree;
// Map of tserver UUID -> its table tree.
typedef std::unordered_map<std::string, PerTServerTableTree> TServerTree;
// Map of zone -> its tserver tree.
typedef std::unordered_map<std::string, TServerTree> ZoneToTServer;
const std::string table_type_[kNumTypes] = {"User", "Index", "Parent", "System"};
const std::string kNoPlacementUUID = "NONE";
static inline void TServerTable(std::stringstream* output, TServersViewType viewType);
void TServerDisplay(const std::string& current_uuid,
std::vector<std::shared_ptr<TSDescriptor>>* descs,
TabletCountMap* tmap,
std::stringstream* output,
const int hide_dead_node_threshold_override,
TServersViewType viewType);
void DisplayUniverseSummary(
const TabletCountMap& tablet_map, const std::vector<std::shared_ptr<TSDescriptor>>& all_descs,
const std::string& live_id,
int hide_dead_node_threshold_mins,
std::stringstream* output);
// Outputs a ZoneTabletCounts::CloudTree as an html table with a heading.
static void DisplayTabletZonesTable(
const ZoneTabletCounts::CloudTree& counts,
std::stringstream* output
);
// Builds a "cloud -> region -> zone" tree of tablet and node counts.
// Each leaf of the tree is a ZoneTabletCounts struct corresponding to the
// unique availability zone identified by the path from the root to the leaf.
ZoneTabletCounts::CloudTree CalculateTabletCountsTree(
const std::vector<std::shared_ptr<TSDescriptor>>& descriptors,
const TabletCountMap& tablet_count_map
);
void CallIfLeaderOrPrintRedirect(const Webserver::WebRequest& req, Webserver::WebResponse* resp,
const Webserver::PathHandlerCallback& callback);
template <class F>
void RegisterPathHandler(
Webserver* server, const std::string& path, const std::string& alias, const F& f,
bool is_styled = false, bool is_on_nav_bar = false, const std::string icon = "") {
server->RegisterPathHandler(
path, alias, std::bind(f, this, std::placeholders::_1, std::placeholders::_2), is_styled,
is_on_nav_bar);
}
template <class F>
void RegisterLeaderOrRedirect(
Webserver* server, const std::string& path, const std::string& alias, const F& f,
bool is_styled = false, bool is_on_nav_bar = false, const std::string& icon = "") {
RegisterLeaderOrRedirectWithArgs(server, path, alias, is_styled, is_on_nav_bar, icon, f);
}
template <class F, class... Args>
void RegisterLeaderOrRedirectWithArgs(
Webserver* server, const std::string& path, const std::string& alias, bool is_styled,
bool is_on_nav_bar, const std::string& icon, const F& f, Args&&... args) {
auto cb = std::bind(
f, this, std::placeholders::_1, std::placeholders::_2, std::forward<Args>(args)...);
server->RegisterPathHandler(
path, alias,
[this, cb = std::move(cb)](
const WebCallbackRegistry::WebRequest& args, WebCallbackRegistry::WebResponse* resp) {
CallIfLeaderOrPrintRedirect(args, resp, cb);
},
is_styled, is_on_nav_bar, icon);
}
void RedirectToLeader(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
Result<std::string> GetLeaderAddress(const Webserver::WebRequest& req);
void RootHandler(const Webserver::WebRequest& req,
Webserver::WebResponse* resp);
void HandleTabletServers(const Webserver::WebRequest& req,
Webserver::WebResponse* resp,
TServersViewType viewType);
void HandleAllTables(
const Webserver::WebRequest& req, Webserver::WebResponse* resp,
bool only_user_tables = false);
void HandleAllTablesJSON(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleNamespacesHTML(const Webserver::WebRequest& req,
Webserver::WebResponse* resp,
bool only_user_namespaces = false);
void HandleNamespacesJSON(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleTablePage(const Webserver::WebRequest& req,
Webserver::WebResponse* resp);
void HandleTablePageJSON(const Webserver::WebRequest& req,
Webserver::WebResponse* resp);
void HandleTasksPage(const Webserver::WebRequest& req,
Webserver::WebResponse* resp);
void HandleTabletReplicasPage(const Webserver::WebRequest &req, Webserver::WebResponse *resp);
void HandleMasters(const Webserver::WebRequest& req,
Webserver::WebResponse* resp);
void HandleDumpEntities(const Webserver::WebRequest& req,
Webserver::WebResponse* resp);
void HandleGetTserverStatus(const Webserver::WebRequest& req,
Webserver::WebResponse* resp);
void HandleGetClusterConfig(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleGetClusterConfigJSON(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleGetXClusterJSON(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void GetXClusterJSON(std::stringstream& output, bool pretty);
void HandleXCluster(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleHealthCheck(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleCheckIfLeader(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleGetMastersStatus(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleGetReplicationStatus(const Webserver::WebRequest &req, Webserver::WebResponse *resp);
void HandleGetUnderReplicationStatus(const Webserver::WebRequest &req,
Webserver::WebResponse *resp);
void HandleVersionInfoDump(const Webserver::WebRequest &req, Webserver::WebResponse *resp);
void HandlePrettyLB(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleLoadBalancer(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
void HandleGetMetaCacheJson(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
// Calcuates number of leaders/followers per table.
void CalculateTabletMap(TabletCountMap* tablet_map);
// Calculate tserver tree for ALL tables if max_table_count == -1.
// Otherwise, do not perform calculation if number of tables is less than max_table_count.
Status CalculateTServerTree(TServerTree* tserver_tree, int max_table_count);
void RenderLoadBalancerViewPanel(
const TServerTree& tserver_tree, const std::vector<std::shared_ptr<TSDescriptor>>& descs,
const std::vector<TableInfoPtr>& tables, std::stringstream* output);
TableType GetTableType(const TableInfo& table);
std::vector<TabletInfoPtr> GetNonSystemTablets();
std::vector<std::pair<TabletInfoPtr, std::string>> GetLeaderlessTablets();
Result<std::vector<std::pair<TabletInfoPtr, std::vector<std::string>>>>
GetUnderReplicatedTablets();
// Calculates the YSQL OID of a tablegroup / colocated database parent table
std::string GetParentTableOid(scoped_refptr<TableInfo> parent_table);
// Convert location of peers to HTML, indicating the roles
// of each tablet server in a consensus configuration.
// This method will display 'locations' in the order given.
std::string RaftConfigToHtml(const std::vector<TabletReplica>& locations,
const std::string& tablet_id) const;
// Convert the specified TSDescriptor to HTML, adding a link to the
// tablet server's own webserver if specified in 'desc'.
std::string TSDescriptorToHtml(const TSDescriptor& desc,
const std::string& tablet_id) const;
// Convert the specified server registration to HTML, adding a link
// to the server's own web server (if specified in 'reg') with
// anchor text 'link_text'.
std::string RegistrationToHtml(
const ServerRegistrationPB& reg, const std::string& link_text) const;
std::string GetHttpHostPortFromServerRegistration(const ServerRegistrationPB& reg) const;
Master* master_;
const int output_precision_;
DISALLOW_COPY_AND_ASSIGN(MasterPathHandlers);
};
void HandleTabletServersPage(const Webserver::WebRequest& req, Webserver::WebResponse* resp);
} // namespace master
} // namespace yb