From 69bb1b67e23fb55e06038586d337deab9c354429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Fri, 24 Jan 2025 13:23:33 +0100 Subject: [PATCH 01/31] HBASE-29223 Migrate Master Status Jamon page back to JSP --- .../master/assignmentManagerStatus.jsp | 117 +++++++++++++ .../resources/hbase-webapps/master/index.html | 2 +- .../resources/hbase-webapps/master/master.jsp | 155 +++++++++++++++++- .../hbase-webapps/master/regionServerList.jsp | 102 ++++++++++++ .../master/regionServerList_baseStats.jsp | 126 ++++++++++++++ .../hbase-webapps/master/rsGroupList.jsp | 46 ++++++ 6 files changed, 546 insertions(+), 2 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/assignmentManagerStatus.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionServerList.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionServerList_baseStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/rsGroupList.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/assignmentManagerStatus.jsp b/hbase-server/src/main/resources/hbase-webapps/master/assignmentManagerStatus.jsp new file mode 100644 index 000000000000..0966d04316b4 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/assignmentManagerStatus.jsp @@ -0,0 +1,117 @@ +<%-- +/** +* 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. +*/ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.quotas.QuotaUtil" + import="org.apache.hadoop.hbase.HBaseConfiguration" + import="org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer" + import="org.apache.hadoop.hbase.master.assignment.AssignmentManager" + import="org.apache.hadoop.hbase.master.RegionState" + import="java.util.SortedSet" + import="org.apache.hadoop.hbase.master.assignment.RegionStates" + import="org.apache.hadoop.hbase.client.RegionInfoDisplay" %> +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + AssignmentManager assignmentManager = master.getAssignmentManager(); + int limit = 100; + + SortedSet rit = assignmentManager.getRegionStates().getRegionsInTransitionOrderedByTimestamp(); + +if (!rit.isEmpty()) { + long currentTime = System.currentTimeMillis(); + AssignmentManager.RegionInTransitionStat ritStat = assignmentManager.computeRegionInTransitionStat(); + + int numOfRITs = rit.size(); + int ritsPerPage = Math.min(5, numOfRITs); + int numOfPages = (int) Math.ceil(numOfRITs * 1.0 / ritsPerPage); +%> +
+

Regions in Transition

+

<%= numOfRITs %> region(s) in transition. + <% if(ritStat.hasRegionsTwiceOverThreshold()) { %> + + <% } else if ( ritStat.hasRegionsOverThreshold()) { %> + + <% } else { %> + + <% } %> + <%= ritStat.getTotalRITsOverThreshold() %> region(s) in transition for + more than <%= ritStat.getRITThreshold() %> milliseconds. + +

+
+
+ <% int recordItr = 0; %> + <% for (RegionState rs : rit) { %> + <% if((recordItr % ritsPerPage) == 0 ) { %> + <% if(recordItr == 0) { %> +
+ <% } else { %> +
+ <% } %> + + + <% } %> + + <% if(ritStat.isRegionTwiceOverThreshold(rs.getRegion())) { %> + + <% } else if ( ritStat.isRegionOverThreshold(rs.getRegion())) { %> + + <% } else { %> + + <% } %> + <% + String retryStatus = "0"; + RegionStates.RegionFailedOpen regionFailedOpen = assignmentManager + .getRegionStates().getFailedOpen(rs.getRegion()); + if (regionFailedOpen != null) { + retryStatus = Integer.toString(regionFailedOpen.getRetries()); + } else if (rs.getState() == RegionState.State.FAILED_OPEN) { + retryStatus = "Failed"; + } + %> + + + + + <% recordItr++; %> + <% if((recordItr % ritsPerPage) == 0) { %> +
RegionStateRIT time (ms) Retries
<%= rs.getRegion().getEncodedName() %> + <%= RegionInfoDisplay.getDescriptiveNameFromRegionStateForDisplay(rs, + assignmentManager.getConfiguration()) %><%= (currentTime - rs.getStamp()) %> <%= retryStatus %>
+
+ <% } %> + <% } %> + + <% if((recordItr % ritsPerPage) != 0) { %> + <% for (; (recordItr % ritsPerPage) != 0 ; recordItr++) { %> + + <% } %> + +
+ <% } %> +
+ + + +
+
+<% } %> + diff --git a/hbase-server/src/main/resources/hbase-webapps/master/index.html b/hbase-server/src/main/resources/hbase-webapps/master/index.html index 0f05414a219b..74c14cb3e64d 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/index.html +++ b/hbase-server/src/main/resources/hbase-webapps/master/index.html @@ -17,4 +17,4 @@ * limitations under the License. */ --> - + diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index 6651c9336b19..bd6ffa837cea 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -17,4 +17,157 @@ * limitations under the License. */ --%> - +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.*" + import="java.net.URLEncoder" + import="java.io.IOException" + import="org.apache.hadoop.hbase.client.replication.ReplicationPeerConfigUtil" + import="org.apache.hadoop.hbase.replication.ReplicationPeerConfig" + import="org.apache.hadoop.hbase.replication.ReplicationPeerDescription" + import="org.apache.hadoop.hbase.HBaseConfiguration" + import="org.apache.hadoop.hbase.HConstants" + import="org.apache.hadoop.hbase.NamespaceDescriptor" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.TableName" + import="org.apache.hadoop.hbase.master.assignment.AssignmentManager" + import="org.apache.hadoop.hbase.master.DeadServer" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.master.RegionState" + import="org.apache.hadoop.hbase.master.ServerManager" + import="org.apache.hadoop.hbase.quotas.QuotaUtil" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfoManager" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" + import="org.apache.hadoop.hbase.security.access.PermissionStorage" + import="org.apache.hadoop.hbase.security.visibility.VisibilityConstants" + import="org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotDescription" + import="org.apache.hadoop.hbase.tool.CanaryTool" + import="org.apache.hadoop.hbase.util.Bytes" + import="org.apache.hadoop.hbase.util.CommonFSUtils" + import="org.apache.hadoop.hbase.util.JvmVersion" + import="org.apache.hadoop.hbase.util.PrettyPrinter" + import="org.apache.hadoop.util.StringUtils" + import="org.apache.hadoop.hbase.master.assignment.RegionStateNode" + import="org.apache.hadoop.hbase.client.*" %> +<%! + private static ServerName getMetaLocationOrNull(HMaster master) { + RegionStateNode rsn = master.getAssignmentManager().getRegionStates() + .getRegionStateNode(RegionInfoBuilder.FIRST_META_REGIONINFO); + if (rsn != null) { + return rsn.isInState(RegionState.State.OPEN) ? rsn.getRegionLocation() : null; + } + return null; + } +%> +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + String title; + if(master.isActiveMaster()) { + title = "Master: "; + } else { + title = "Backup Master: "; + } + title += master.getServerName().getHostname(); + pageContext.setAttribute("pageTitle", title); + + boolean catalogJanitorEnabled = master.isCatalogJanitorEnabled(); + ServerManager serverManager = master.getServerManager(); + + ServerName metaLocation = null; + List servers = null; + Set deadServers = null; + + if (master.isActiveMaster()) { + metaLocation = getMetaLocationOrNull(master); + if (serverManager != null) { + deadServers = serverManager.getDeadServers().copyServerNames(); + servers = serverManager.getOnlineServersList(); + } + } +%> + + + + + +
+ <% if(master.isActiveMaster()) { %> +
+ +
+ +
+ + <% if(JvmVersion.isBadJvmVersion()) { %> + + <% } %> + <% if(master.isInitialized() && !catalogJanitorEnabled) { %> + + <% } %> + <% if(master.isInMaintenanceMode()) { %> + + <% } %> + <% if(!master.isBalancerOn()) { %> + + <% } %> + <% if(!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) { %> + + <% } %> + <% if(!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) { %> + + <% } %> + <% if(master.getAssignmentManager() != null) { %> + + <% } %> + <% if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null) { %> + <% if (RSGroupUtil.isRSGroupEnabled(master.getConfiguration()) && + serverManager.getOnlineServersList().size() > 0) { %> +
+

RSGroup

+ +
+ <% } %> + <% } %> +
+
+
+

Region Servers

+ + + <%if (deadServers != null) %> + <& deadRegionServers &> TODO + +
+
+ + TODO + + <% } %> +
+ + diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList.jsp new file mode 100644 index 000000000000..34e67d75c47c --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList.jsp @@ -0,0 +1,102 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="static org.apache.commons.lang3.StringEscapeUtils.escapeXml" + import="java.util.*" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.procedure2.util.StringUtils" + import="org.apache.hadoop.hbase.replication.ReplicationLoadSource" + import="org.apache.hadoop.hbase.RegionMetrics" + import="org.apache.hadoop.hbase.ServerMetrics" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.Size" + import="org.apache.hadoop.hbase.util.VersionInfo" + import="org.apache.hadoop.hbase.util.Pair" + import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix" + import="org.apache.hadoop.hbase.net.Address" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" %> +<%@ page import="org.apache.hadoop.hbase.master.ServerManager" %> + +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + ServerManager serverManager = master.getServerManager(); + + List servers = null; + + if (master.isActiveMaster()) { + if (serverManager != null) { + servers = serverManager.getOnlineServersList(); + } + } +%> + +<% + if (servers != null && servers.size() > 0) { + + ServerName [] serverNames = servers.toArray(new ServerName[servers.size()]); + Arrays.sort(serverNames); +%> + +
+ +
+
+ <% request.setAttribute("serverNames", serverNames); %> + +
+
+ <& memoryStats; serverNames = serverNames; &> +
+
+ <& requestStats; serverNames = serverNames; &> +
+
+ <& storeStats; serverNames = serverNames; &> +
+
+ <& compactionStats; serverNames = serverNames; &> +
+
+ <& replicationStats; serverNames = serverNames; &> +
+
+
+ +<% } %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_baseStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_baseStats.jsp new file mode 100644 index 000000000000..e6a760c38e4b --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_baseStats.jsp @@ -0,0 +1,126 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.master.HMaster" %> +<%@ page import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" %> +<%@ page import="org.apache.hadoop.hbase.util.VersionInfo" %> +<%@ page import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" %> +<%@ page import="org.apache.hadoop.hbase.net.Address" %> +<%@ page import="java.util.*" %> +<%@ page import="org.apache.hadoop.hbase.ServerMetrics" %> +<%@ page import="org.apache.hadoop.util.StringUtils" %> + +<% + ServerName[] serverNames = (ServerName[]) request.getAttribute("serverNames"); // TODO: intro constant! + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); +%> + + + + + + + + + + + + <% if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null) { %> + <% if (RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { %> + + <% } %> + <% } %> + + + + <% + int totalRegions = 0; + int totalRequestsPerSecond = 0; + int inconsistentNodeNum = 0; + String state = "Normal"; + String masterVersion = VersionInfo.getVersion(); + Set decommissionedServers = new HashSet<>(master.listDecommissionedRegionServers()); + String rsGroupName = "default"; + List groups; + Map server2GroupMap = new HashMap<>(); + if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null + && RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { + groups = master.getRSGroupInfoManager().listRSGroups(); + groups.forEach(group -> { + group.getServers().forEach(address -> server2GroupMap.put(address, group)); + }); + } + for (ServerName serverName: serverNames) { + if (decommissionedServers.contains(serverName)) { + state = "Decommissioned"; + } + ServerMetrics sl = master.getServerManager().getLoad(serverName); + String version = master.getRegionServerVersion(serverName); + if (!masterVersion.equals(version)) { + inconsistentNodeNum ++; + } + + double requestsPerSecond = 0.0; + int numRegionsOnline = 0; + long lastContact = 0; + + if (sl != null) { + requestsPerSecond = sl.getRequestCountPerSecond(); + numRegionsOnline = sl.getRegionMetrics().size(); + totalRegions += sl.getRegionMetrics().size(); + totalRequestsPerSecond += sl.getRequestCountPerSecond(); + lastContact = (System.currentTimeMillis() - sl.getReportTimestamp())/1000; + } + long startcode = serverName.getStartcode(); + if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null + && RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { + rsGroupName = server2GroupMap.get(serverName.getAddress()).getName(); + } +%> + + + + + + + + + <% if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null) { %> + <% if (RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { %> + + <% } %> + <% } %> + +<% } %> + + + + + +<% if(inconsistentNodeNum > 0) {%> + +<% } else { %> + +<% } %> + + + +
ServerNameStateStart timeLast contactVersionRequests Per SecondNum. RegionsRSGroup
<& serverNameLink; serverName=serverName; &><%= state %><%= new Date(startcode) %><%= StringUtils.TraditionalBinaryPrefix.long2String(lastContact, "s", 1) %><%= version %><%= String.format("%,.0f", requestsPerSecond) %><%= String.format("%,d", numRegionsOnline) %><%= rsGroupName %>
Total:<%= serverNames.length %><%= inconsistentNodeNum %> nodes with inconsistent version<%= totalRequestsPerSecond %><%= totalRegions %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList.jsp b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList.jsp new file mode 100644 index 000000000000..e34634f83241 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList.jsp @@ -0,0 +1,46 @@ +<%-- +/** +* 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. +*/ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.master.HMaster" + import="java.util.Collections" + import="java.util.List" + import="java.util.Map" + import="java.util.Set" + import="java.util.stream.Collectors" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.RegionMetrics" + import="org.apache.hadoop.hbase.ServerMetrics" + import="org.apache.hadoop.hbase.Size" + import="org.apache.hadoop.hbase.master.ServerManager" + import="org.apache.hadoop.hbase.net.Address" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" + import="org.apache.hadoop.util.StringUtils" + import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix" + import="org.apache.hadoop.hbase.master.assignment.AssignmentManager" %> + +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + AssignmentManager assignmentManager = master.getAssignmentManager(); + List groups = master.getRSGroupInfoManager().listRSGroups(); + +%> + +TODO: rsGroupList.jsp From f144d37fc1de8a0355c74b1e6be962fe504e8d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Thu, 27 Mar 2025 17:20:24 +0100 Subject: [PATCH 02/31] HBASE-29223 Dead Region Servers, Region Server List sections --- .../master/backupMasterStatus.jsp | 66 ++++++++++ .../master/deadRegionServers.jsp | 79 ++++++++++++ .../resources/hbase-webapps/master/master.jsp | 12 +- .../hbase-webapps/master/regionServerList.jsp | 26 ++-- .../master/regionServerList_baseStats.jsp | 17 ++- .../regionServerList_compactionStats.jsp | 87 +++++++++++++ .../master/regionServerList_emptyStat.jsp | 47 +++++++ .../master/regionServerList_memoryStats.jsp | 99 +++++++++++++++ .../regionServerList_replicationStats.jsp | 101 +++++++++++++++ .../master/regionServerList_requestStats.jsp | 84 +++++++++++++ .../master/regionServerList_storeStats.jsp | 117 ++++++++++++++++++ 11 files changed, 710 insertions(+), 25 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/backupMasterStatus.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/deadRegionServers.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionServerList_compactionStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionServerList_emptyStat.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionServerList_memoryStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionServerList_replicationStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionServerList_requestStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionServerList_storeStats.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/backupMasterStatus.jsp b/hbase-server/src/main/resources/hbase-webapps/master/backupMasterStatus.jsp new file mode 100644 index 000000000000..ee183b51a785 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/backupMasterStatus.jsp @@ -0,0 +1,66 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.*" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hbase.thirdparty.com.google.common.base.Preconditions" %> +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + if (!master.isActiveMaster()) { + + ServerName active_master = master.getActiveMaster().orElse(null); + Preconditions.checkState(active_master != null, "Failed to retrieve active master's ServerName!"); + int activeInfoPort = master.getActiveMasterInfoPort(); +%> +
+ +
+

Current Active Master: <%= active_master.getHostname() %>

+ <% } else { %> +

Backup Masters

+ + + + + + + + <% + Collection backup_masters = master.getBackupMasters(); + ServerName [] backupServerNames = backup_masters.toArray(new ServerName[backup_masters.size()]); + Arrays.sort(backupServerNames); + for (ServerName serverName : backupServerNames) { + int infoPort = master.getBackupMasterInfoPort(serverName); + %> + + + + + + <% } %> + +
ServerNamePortStart Time
<%= serverName.getHostname() %> + <%= serverName.getPort() %><%= new Date(serverName.getStartCode()) %>
Total:<%= backupServerNames.length %>
+<% } %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/deadRegionServers.jsp b/hbase-server/src/main/resources/hbase-webapps/master/deadRegionServers.jsp new file mode 100644 index 000000000000..7de91db80f4b --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/deadRegionServers.jsp @@ -0,0 +1,79 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.ServerName" + import="java.util.*" + import="org.apache.hadoop.hbase.master.HMaster" %> +<%@ page import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" %> +<%@ page import="org.apache.hadoop.hbase.rsgroup.RSGroupInfoManager" %> +<%@ page import="org.apache.hadoop.hbase.master.DeadServer" %> +<%@ page import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" %> +<% + Set deadServers = (Set) request.getAttribute("deadServers"); // TODO: intro constant! + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); +%> + +<% if (deadServers != null && deadServers.size() > 0) { %> +

Dead Region Servers

+ + + + + + <% if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null) { %> + <% if (RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { %> + + <% } %> + <% } %> + +<% + RSGroupInfoManager inMgr = null; + DeadServer deadServerUtil = master.getServerManager().getDeadServers(); + ServerName [] deadServerNames = deadServers.toArray(new ServerName[deadServers.size()]); + Arrays.sort(deadServerNames); + if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null + && RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { + inMgr = master.getRSGroupInfoManager(); + } + for (ServerName deadServerName: deadServerNames) { + String rsGroupName = null; + if (inMgr != null){ + RSGroupInfo groupInfo = inMgr.getRSGroupOfServer(deadServerName.getAddress()); + rsGroupName = groupInfo == null ? RSGroupInfo.DEFAULT_GROUP : groupInfo.getName(); + } + %> + + + + + <% if (rsGroupName != null) { %> + + <% } %> + + <% + } + %> + + + + + +
ServerNameStop timeRSGroup
<%= deadServerName %><%= deadServerUtil.getTimeOfDeath(deadServerName) %><%= rsGroupName %>
Total: servers: <%= deadServers.size() %>
+<% } %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index bd6ffa837cea..4aee9814011f 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -159,9 +159,15 @@

Region Servers

- <%if (deadServers != null) %> - <& deadRegionServers &> TODO - + <% if (deadServers != null) { %> + <% request.setAttribute("deadServers", deadServers); %> + + <% } %> + + +
+
+
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList.jsp index 34e67d75c47c..deabce6dca2f 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList.jsp @@ -18,22 +18,10 @@ */ --%> <%@ page contentType="text/html;charset=UTF-8" - import="static org.apache.commons.lang3.StringEscapeUtils.escapeXml" import="java.util.*" import="org.apache.hadoop.hbase.master.HMaster" - import="org.apache.hadoop.hbase.procedure2.util.StringUtils" - import="org.apache.hadoop.hbase.replication.ReplicationLoadSource" - import="org.apache.hadoop.hbase.RegionMetrics" - import="org.apache.hadoop.hbase.ServerMetrics" import="org.apache.hadoop.hbase.ServerName" - import="org.apache.hadoop.hbase.Size" - import="org.apache.hadoop.hbase.util.VersionInfo" - import="org.apache.hadoop.hbase.util.Pair" - import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix" - import="org.apache.hadoop.hbase.net.Address" - import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" - import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" %> -<%@ page import="org.apache.hadoop.hbase.master.ServerManager" %> + import="org.apache.hadoop.hbase.master.ServerManager" %> <% HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); @@ -77,24 +65,24 @@
+ <% request.setAttribute("serverNames", serverNames); %>
- <% request.setAttribute("serverNames", serverNames); %>
- <& memoryStats; serverNames = serverNames; &> +
- <& requestStats; serverNames = serverNames; &> +
- <& storeStats; serverNames = serverNames; &> +
- <& compactionStats; serverNames = serverNames; &> +
- <& replicationStats; serverNames = serverNames; &> +
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_baseStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_baseStats.jsp index e6a760c38e4b..6a924a826fde 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_baseStats.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_baseStats.jsp @@ -27,7 +27,18 @@ <%@ page import="java.util.*" %> <%@ page import="org.apache.hadoop.hbase.ServerMetrics" %> <%@ page import="org.apache.hadoop.util.StringUtils" %> - +<%! + // TODO: Extract to common place! + private static String serverNameLink(HMaster master, ServerName serverName) { + int infoPort = master.getRegionServerInfoPort(serverName); + String url = "//" + serverName.getHostname() + ":" + infoPort + "/rs-status"; + if (infoPort > 0) { + return "" + serverName.getServerName() + ""; + } else { + return serverName.getServerName(); + } + } +%> <% ServerName[] serverNames = (ServerName[]) request.getAttribute("serverNames"); // TODO: intro constant! HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); @@ -96,8 +107,8 @@ } %> - <& serverNameLink; serverName=serverName; &> - <%= state %> + <%= serverNameLink(master, serverName) %> + <%= state %> <%= new Date(startcode) %> <%= StringUtils.TraditionalBinaryPrefix.long2String(lastContact, "s", 1) %> <%= version %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_compactionStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_compactionStats.jsp new file mode 100644 index 000000000000..8a34c3fa1f65 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_compactionStats.jsp @@ -0,0 +1,87 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.master.HMaster" %> +<%@ page import="org.apache.hadoop.hbase.ServerMetrics" %> +<%@ page import="org.apache.hadoop.hbase.RegionMetrics" %> +<%! + // TODO: Extract to common place! + private static String serverNameLink(HMaster master, ServerName serverName) { + int infoPort = master.getRegionServerInfoPort(serverName); + String url = "//" + serverName.getHostname() + ":" + infoPort + "/rs-status"; + if (infoPort > 0) { + return "" + serverName.getServerName() + ""; + } else { + return serverName.getServerName(); + } + } +%> +<% + ServerName[] serverNames = (ServerName[]) request.getAttribute("serverNames"); // TODO: intro constant! + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); +%> + + + + + + + + + + + + + <% +for (ServerName serverName: serverNames) { + +ServerMetrics sl = master.getServerManager().getLoad(serverName); +if (sl != null) { +long totalCompactingCells = 0; +long totalCompactedCells = 0; +for (RegionMetrics rl : sl.getRegionMetrics().values()) { + totalCompactingCells += rl.getCompactingCellCount(); + totalCompactedCells += rl.getCompactedCellCount(); +} +String percentDone = ""; +if (totalCompactingCells > 0) { + percentDone = String.format("%.2f", 100 * + ((float) totalCompactedCells / totalCompactingCells)) + "%"; +} +%> + + + + + + + +<% +} else { +%> + <% request.setAttribute("serverName", serverName); %> + +<% + } +} +%> + +
ServerNameNum. Compacting CellsNum. Compacted CellsRemaining CellsCompaction Progress
<%= serverNameLink(master, serverName) %><%= String.format("%,d", totalCompactingCells) %><%= String.format("%,d", totalCompactedCells) %><%= String.format("%,d", totalCompactingCells - totalCompactedCells) %><%= percentDone %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_emptyStat.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_emptyStat.jsp new file mode 100644 index 000000000000..3ebe3feb188f --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_emptyStat.jsp @@ -0,0 +1,47 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.master.HMaster" %> +<%! + // TODO: Extract to common place! + private static String serverNameLink(HMaster master, ServerName serverName) { + int infoPort = master.getRegionServerInfoPort(serverName); + String url = "//" + serverName.getHostname() + ":" + infoPort + "/rs-status"; + if (infoPort > 0) { + return "" + serverName.getServerName() + ""; + } else { + return serverName.getServerName(); + } + } +%> +<% + ServerName serverName = (ServerName) request.getAttribute("serverName"); // TODO: intro constant! + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); +%> + +<%= serverNameLink(master, serverName) %> + + + + + + + diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_memoryStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_memoryStats.jsp new file mode 100644 index 000000000000..ae77bab8e475 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_memoryStats.jsp @@ -0,0 +1,99 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.master.HMaster" %> +<%@ page import="org.apache.hadoop.hbase.ServerMetrics" %> +<%@ page import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix" %> +<%@ page import="org.apache.hadoop.hbase.RegionMetrics" %> +<%@ page import="org.apache.hadoop.hbase.Size" %> +<%! + // TODO: Extract to common place! + private static String serverNameLink(HMaster master, ServerName serverName) { + int infoPort = master.getRegionServerInfoPort(serverName); + String url = "//" + serverName.getHostname() + ":" + infoPort + "/rs-status"; + if (infoPort > 0) { + return "" + serverName.getServerName() + ""; + } else { + return serverName.getServerName(); + } + } +%> +<% + ServerName[] serverNames = (ServerName[]) request.getAttribute("serverNames"); // TODO: intro constant! + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); +%> + + + + + + + + + + + + +<% +final String ZEROMB = "0 MB"; +for (ServerName serverName: serverNames) { + String usedHeapStr = ZEROMB; + String maxHeapStr = ZEROMB; + String memStoreSizeMBStr = ZEROMB; + ServerMetrics sl = master.getServerManager().getLoad(serverName); + if (sl != null) { + long memStoreSizeMB = 0; + for (RegionMetrics rl : sl.getRegionMetrics().values()) { + memStoreSizeMB += rl.getMemStoreSize().get(Size.Unit.MEGABYTE); + } + if (memStoreSizeMB > 0) { + memStoreSizeMBStr = TraditionalBinaryPrefix.long2String(memStoreSizeMB + * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } + + double usedHeapSizeMB = sl.getUsedHeapSize().get(Size.Unit.MEGABYTE); + if (usedHeapSizeMB > 0) { + usedHeapStr = TraditionalBinaryPrefix.long2String((long) usedHeapSizeMB + * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } + double maxHeapSizeMB = sl.getMaxHeapSize().get(Size.Unit.MEGABYTE); + if (maxHeapSizeMB > 0) { + maxHeapStr = TraditionalBinaryPrefix.long2String((long) maxHeapSizeMB + * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } +%> + + + + + + +<% +} else { +%> + <% request.setAttribute("serverName", serverName); %> + +<% + } +} +%> + +
ServerNameUsed HeapMax HeapMemstore Size
<%= serverNameLink(master, serverName) %><%= usedHeapStr %><%= maxHeapStr %><%= memStoreSizeMBStr %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_replicationStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_replicationStats.jsp new file mode 100644 index 000000000000..79e54c4b2afb --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_replicationStats.jsp @@ -0,0 +1,101 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.master.HMaster" %> +<%@ page import="org.apache.hadoop.hbase.replication.ReplicationLoadSource" %> +<%@ page import="org.apache.hadoop.hbase.util.Pair" %> +<%@ page import="java.util.*" %> +<%@ page import="org.apache.hadoop.hbase.procedure2.util.StringUtils" %> +<%! + // TODO: Extract to common place! + private static String serverNameLink(HMaster master, ServerName serverName) { + int infoPort = master.getRegionServerInfoPort(serverName); + String url = "//" + serverName.getHostname() + ":" + infoPort + "/rs-status"; + if (infoPort > 0) { + return "" + serverName.getServerName() + ""; + } else { + return serverName.getServerName(); + } + } +%> +<% + ServerName[] serverNames = (ServerName[]) request.getAttribute("serverNames"); // TODO: intro constant! + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); +%> + +<% + HashMap>> replicationLoadSourceMap + = master.getReplicationLoad(serverNames); + List peers = null; + if (replicationLoadSourceMap != null && replicationLoadSourceMap.size() > 0){ + peers = new ArrayList<>(replicationLoadSourceMap.keySet()); + Collections.sort(peers); + } +%> + +<% if (replicationLoadSourceMap != null && replicationLoadSourceMap.size() > 0) { %> + +
+ +
+ <% + active = "active"; + for (String peer : peers){ + %> +
+ + + + + + + + + <% for (Pair pair: replicationLoadSourceMap.get(peer)) { %> + + + + + + + <% } %> +
ServerAgeOfLastShippedOpSizeOfLogQueueReplicationLag
<%= serverNameLink(master, pair.getFirst()) %><%= StringUtils.humanTimeDiff(pair.getSecond().getAgeOfLastShippedOp()) %><%= pair.getSecond().getSizeOfLogQueue() %><%= pair.getSecond().getReplicationLag() == Long.MAX_VALUE ? "UNKNOWN" : StringUtils.humanTimeDiff(pair.getSecond().getReplicationLag()) %>
+
+<% + active = ""; + } + %> +
+

If the replication delay is UNKNOWN, that means this walGroup doesn't start replicate yet and it may get disabled.

+
+<% } else { %> +

No Peers Metrics

+<% } %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_requestStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_requestStats.jsp new file mode 100644 index 000000000000..09f7041bb16b --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_requestStats.jsp @@ -0,0 +1,84 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.master.HMaster" %> +<%@ page import="org.apache.hadoop.hbase.ServerMetrics" %> +<%@ page import="org.apache.hadoop.hbase.RegionMetrics" %> +<%! + // TODO: Extract to common place! + private static String serverNameLink(HMaster master, ServerName serverName) { + int infoPort = master.getRegionServerInfoPort(serverName); + String url = "//" + serverName.getHostname() + ":" + infoPort + "/rs-status"; + if (infoPort > 0) { + return "" + serverName.getServerName() + ""; + } else { + return serverName.getServerName(); + } + } +%> +<% + ServerName[] serverNames = (ServerName[]) request.getAttribute("serverNames"); // TODO: intro constant! + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); +%> + + + + + + + + + + + + +<% + for (ServerName serverName: serverNames) { + + ServerMetrics sl = master.getServerManager().getLoad(serverName); + if (sl != null) { + long readRequestCount = 0; + long writeRequestCount = 0; + long filteredReadRequestCount = 0; + for (RegionMetrics rl : sl.getRegionMetrics().values()) { + readRequestCount += rl.getReadRequestCount(); + writeRequestCount += rl.getWriteRequestCount(); + filteredReadRequestCount += rl.getFilteredReadRequestCount(); + } +%> + + + + + + + +<% +} else { +%> + <% request.setAttribute("serverName", serverName); %> + +<% + } +} +%> + +
ServerNameRequest Per SecondRead Request CountFiltered Read Request CountWrite Request Count
<%= serverNameLink(master, serverName) %><%= String.format("%,d", sl.getRequestCountPerSecond()) %><%= String.format("%,d", readRequestCount) %><%= String.format("%,d", filteredReadRequestCount) %><%= String.format("%,d", writeRequestCount) %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_storeStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_storeStats.jsp new file mode 100644 index 000000000000..c00add31dc60 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionServerList_storeStats.jsp @@ -0,0 +1,117 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.ServerName" + import="org.apache.hadoop.hbase.master.HMaster" %> +<%@ page import="org.apache.hadoop.hbase.ServerMetrics" %> +<%@ page import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix" %> +<%@ page import="org.apache.hadoop.hbase.RegionMetrics" %> +<%@ page import="org.apache.hadoop.hbase.Size" %> +<%! + // TODO: Extract to common place! + private static String serverNameLink(HMaster master, ServerName serverName) { + int infoPort = master.getRegionServerInfoPort(serverName); + String url = "//" + serverName.getHostname() + ":" + infoPort + "/rs-status"; + if (infoPort > 0) { + return "" + serverName.getServerName() + ""; + } else { + return serverName.getServerName(); + } + } +%> +<% + ServerName[] serverNames = (ServerName[]) request.getAttribute("serverNames"); // TODO: intro constant! + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); +%> + + + + + + + + + + + + + + <% +final String ZEROKB = "0 KB"; +final String ZEROMB = "0 MB"; +for (ServerName serverName: serverNames) { + + String storeUncompressedSizeMBStr = ZEROMB; + String storeFileSizeMBStr = ZEROMB; + String totalStaticIndexSizeKBStr = ZEROKB; + String totalStaticBloomSizeKBStr = ZEROKB; + ServerMetrics sl = master.getServerManager().getLoad(serverName); + if (sl != null) { + long storeCount = 0; + long storeFileCount = 0; + long storeUncompressedSizeMB = 0; + long storeFileSizeMB = 0; + long totalStaticIndexSizeKB = 0; + long totalStaticBloomSizeKB = 0; + for (RegionMetrics rl : sl.getRegionMetrics().values()) { + storeCount += rl.getStoreCount(); + storeFileCount += rl.getStoreFileCount(); + storeUncompressedSizeMB += rl.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE); + storeFileSizeMB += rl.getStoreFileSize().get(Size.Unit.MEGABYTE); + totalStaticIndexSizeKB += rl.getStoreFileUncompressedDataIndexSize().get(Size.Unit.KILOBYTE); + totalStaticBloomSizeKB += rl.getBloomFilterSize().get(Size.Unit.KILOBYTE); + } + if (storeUncompressedSizeMB > 0) { + storeUncompressedSizeMBStr = TraditionalBinaryPrefix. + long2String(storeUncompressedSizeMB * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } + if (storeFileSizeMB > 0) { + storeFileSizeMBStr = TraditionalBinaryPrefix. + long2String(storeFileSizeMB * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } + if (totalStaticIndexSizeKB > 0) { + totalStaticIndexSizeKBStr = TraditionalBinaryPrefix. + long2String(totalStaticIndexSizeKB * TraditionalBinaryPrefix.KILO.value, "B", 1); + } + if (totalStaticBloomSizeKB > 0) { + totalStaticBloomSizeKBStr = TraditionalBinaryPrefix. + long2String(totalStaticBloomSizeKB * TraditionalBinaryPrefix.KILO.value, "B", 1); + } +%> + + + + + + + + + +<% +} else { +%> + <% request.setAttribute("serverName", serverName); %> + +<% + } +} +%> + +
ServerNameNum. StoresNum. StorefilesStorefile Size UncompressedStorefile SizeIndex SizeBloom Size
<%= serverNameLink(master, serverName) %><%= String.format("%,d", storeCount) %><%= String.format("%,d", storeFileCount) %><%= storeUncompressedSizeMBStr %><%= storeFileSizeMBStr %><%= totalStaticIndexSizeKBStr %><%= totalStaticBloomSizeKBStr %>
From 4e053fc2ef913ab1dfb6a790e49e5e7b7b9c5671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Fri, 28 Mar 2025 11:14:22 +0100 Subject: [PATCH 03/31] HBASE-29223 Region Server Group list --- .../hbase-webapps/master/rsGroupList.jsp | 53 +++++++-- .../master/rsGroupList_baseStats.jsp | 109 ++++++++++++++++++ .../master/rsGroupList_compactStats.jsp | 79 +++++++++++++ .../master/rsGroupList_memoryStats.jsp | 91 +++++++++++++++ .../master/rsGroupList_requestStats.jsp | 72 ++++++++++++ .../master/rsGroupList_storeStats.jsp | 108 +++++++++++++++++ 6 files changed, 501 insertions(+), 11 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_baseStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_compactStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_memoryStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_requestStats.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_storeStats.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList.jsp b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList.jsp index e34634f83241..4d65b2f93c31 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList.jsp @@ -22,25 +22,56 @@ import="java.util.Collections" import="java.util.List" import="java.util.Map" - import="java.util.Set" import="java.util.stream.Collectors" import="org.apache.hadoop.hbase.master.HMaster" - import="org.apache.hadoop.hbase.RegionMetrics" import="org.apache.hadoop.hbase.ServerMetrics" - import="org.apache.hadoop.hbase.Size" - import="org.apache.hadoop.hbase.master.ServerManager" import="org.apache.hadoop.hbase.net.Address" - import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" - import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" - import="org.apache.hadoop.util.StringUtils" - import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix" - import="org.apache.hadoop.hbase.master.assignment.AssignmentManager" %> + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" %> <% HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); - AssignmentManager assignmentManager = master.getAssignmentManager(); List groups = master.getRSGroupInfoManager().listRSGroups(); +%> + +<%if (groups != null && groups.size() > 0)%> +<% + RSGroupInfo [] rsGroupInfos = groups.toArray(new RSGroupInfo[groups.size()]); + Map collectServers = Collections.emptyMap(); + if (master.getServerManager() != null) { + collectServers = + master.getServerManager().getOnlineServers().entrySet().stream() + .collect(Collectors.toMap(p -> p.getKey().getAddress(), Map.Entry::getValue)); + } %> -TODO: rsGroupList.jsp +
+ +
+ + <% request.setAttribute("rsGroupInfos", rsGroupInfos); %> + <% request.setAttribute("collectServers", collectServers); %> + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_baseStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_baseStats.jsp new file mode 100644 index 000000000000..bef9358ae15b --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_baseStats.jsp @@ -0,0 +1,109 @@ +<%-- +/** +* 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. +*/ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.master.HMaster" + import="java.util.Map" + import="java.util.Set" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.ServerMetrics" + import="org.apache.hadoop.hbase.net.Address" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" + import="org.apache.hadoop.util.StringUtils" %> + +<%! + // TODO: Extract to common place! + private static String rsGroupLink(String rsGroupName) { + return "" + rsGroupName + ""; + } +%> + +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + RSGroupInfo [] rsGroupInfos = (RSGroupInfo[]) request.getAttribute("rsGroupInfos"); // TODO: intro constant! + Map collectServers = (Map) request.getAttribute("collectServers"); // TODO: intro constant! +%> + + + + + + + + + + + + <% + int totalOnlineServers = 0; + int totalDeadServers = 0; + int totalTables = 0; + int totalRequests = 0; + int totalRegions = 0; + for (RSGroupInfo rsGroupInfo: rsGroupInfos) { + String rsGroupName = rsGroupInfo.getName(); + int onlineServers = 0; + int deadServers = 0; + int tables = 0; + long requestsPerSecond = 0; + int numRegionsOnline = 0; + Set
servers = rsGroupInfo.getServers(); + for (Address server : servers) { + ServerMetrics sl = collectServers.get(server); + if (sl != null) { + requestsPerSecond += sl.getRequestCountPerSecond(); + numRegionsOnline += sl.getRegionMetrics().size(); + //rsgroup total + totalRegions += sl.getRegionMetrics().size(); + totalRequests += sl.getRequestCountPerSecond(); + totalOnlineServers++; + onlineServers++; + } else { + totalDeadServers++; + deadServers++; + } + } + tables = RSGroupUtil.listTablesInRSGroup(master, rsGroupInfo.getName()).size(); + totalTables += tables; + double avgLoad = onlineServers == 0 ? 0 : + (double)numRegionsOnline / (double)onlineServers; +%> +
+ + + + + + + + +<% + } +%> + + + + + + + + + +
RSGroup NameNum. Online ServersNum. Dead ServersNum. TablesRequests Per SecondNum. RegionsAverage Load
<%= rsGroupLink(rsGroupName) %><%= onlineServers %><%= deadServers %><%= tables %><%= requestsPerSecond %><%= numRegionsOnline %><%= StringUtils.limitDecimalTo2(avgLoad) %>
Total:<%= rsGroupInfos.length %><%= totalOnlineServers %><%= totalDeadServers %><%= totalTables %><%= totalRequests %><%= totalRegions %><%= StringUtils.limitDecimalTo2(master.getServerManager().getAverageLoad()) %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_compactStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_compactStats.jsp new file mode 100644 index 000000000000..4eb7fccccaac --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_compactStats.jsp @@ -0,0 +1,79 @@ +<%-- +/** +* 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. +*/ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.Map" + import="org.apache.hadoop.hbase.ServerMetrics" + import="org.apache.hadoop.hbase.net.Address" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.hbase.RegionMetrics" %> + +<%! + // TODO: Extract to common place! + private static String rsGroupLink(String rsGroupName) { + return "" + rsGroupName + ""; + } +%> + +<% + RSGroupInfo [] rsGroupInfos = (RSGroupInfo[]) request.getAttribute("rsGroupInfos"); // TODO: intro constant! + Map collectServers = (Map) request.getAttribute("collectServers"); // TODO: intro constant! +%> + + + + + + + + + + <% + for (RSGroupInfo rsGroupInfo: rsGroupInfos) { + String rsGroupName = rsGroupInfo.getName(); + long totalCompactingCells = 0; + long totalCompactedCells = 0; + long remainingCells = 0; + for (Address server : rsGroupInfo.getServers()) { + ServerMetrics sl = collectServers.get(server); + if (sl != null) { + for (RegionMetrics rl : sl.getRegionMetrics().values()) { + totalCompactingCells += rl.getCompactingCellCount(); + totalCompactedCells += rl.getCompactedCellCount(); + } + } + } + remainingCells = totalCompactingCells - totalCompactedCells; + String percentDone = ""; + if (totalCompactingCells > 0) { + percentDone = String.format("%.2f", 100 * + ((float) totalCompactedCells / totalCompactingCells)) + "%"; + } +%> + + + + + + + +<% +} +%> +
RSGroup NameNum. Compacting CellsNum. Compacted CellsRemaining CellsCompaction Progress
<%= rsGroupLink(rsGroupName) %><%= totalCompactingCells %><%= totalCompactedCells %><%= remainingCells %><%= percentDone %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_memoryStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_memoryStats.jsp new file mode 100644 index 000000000000..39844211e5cc --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_memoryStats.jsp @@ -0,0 +1,91 @@ +<%-- +/** +* 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. +*/ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.Map" + import="org.apache.hadoop.hbase.ServerMetrics" + import="org.apache.hadoop.hbase.Size" + import="org.apache.hadoop.hbase.net.Address" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix" %> + +<%! + // TODO: Extract to common place! + private static String rsGroupLink(String rsGroupName) { + return "" + rsGroupName + ""; + } +%> + +<% + RSGroupInfo [] rsGroupInfos = (RSGroupInfo[]) request.getAttribute("rsGroupInfos"); // TODO: intro constant! + Map collectServers = (Map) request.getAttribute("collectServers"); // TODO: intro constant! +%> + + + + + + + + + + <% + final String ZEROMB = "0 MB"; + for (RSGroupInfo rsGroupInfo: rsGroupInfos) { + String usedHeapStr = ZEROMB; + String maxHeapStr = ZEROMB; + String memstoreSizeStr = ZEROMB; + String rsGroupName = rsGroupInfo.getName(); + long usedHeap = 0; + long maxHeap = 0; + long memstoreSize = 0; + for (Address server : rsGroupInfo.getServers()) { + ServerMetrics sl = collectServers.get(server); + if (sl != null) { + usedHeap += (long) sl.getUsedHeapSize().get(Size.Unit.MEGABYTE); + maxHeap += (long) sl.getMaxHeapSize().get(Size.Unit.MEGABYTE); + memstoreSize += (long) sl.getRegionMetrics().values().stream().mapToDouble( + rm -> rm.getMemStoreSize().get(Size.Unit.MEGABYTE)).sum(); + } + } + + if (usedHeap > 0) { + usedHeapStr = TraditionalBinaryPrefix.long2String(usedHeap + * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } + if (maxHeap > 0) { + maxHeapStr = TraditionalBinaryPrefix.long2String(maxHeap + * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } + if (memstoreSize > 0) { + memstoreSizeStr = TraditionalBinaryPrefix.long2String(memstoreSize + * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } +%> + + + + + + + +<% +} +%> +
RSGroup NameUsed HeapMax HeapMemstore Size
<%= rsGroupLink(rsGroupName) %><%= usedHeapStr %><%= maxHeapStr %><%= memstoreSizeStr %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_requestStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_requestStats.jsp new file mode 100644 index 000000000000..0d9abaf94d35 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_requestStats.jsp @@ -0,0 +1,72 @@ +<%-- +/** +* 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. +*/ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.Map" + import="org.apache.hadoop.hbase.ServerMetrics" + import="org.apache.hadoop.hbase.net.Address" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.hbase.RegionMetrics" %> + +<%! + // TODO: Extract to common place! + private static String rsGroupLink(String rsGroupName) { + return "" + rsGroupName + ""; + } +%> + +<% + RSGroupInfo [] rsGroupInfos = (RSGroupInfo[]) request.getAttribute("rsGroupInfos"); // TODO: intro constant! + Map collectServers = (Map) request.getAttribute("collectServers"); // TODO: intro constant! +%> + + + + + + + + + <% + for (RSGroupInfo rsGroupInfo: rsGroupInfos) { + String rsGroupName = rsGroupInfo.getName(); + long requestsPerSecond = 0; + long readRequests = 0; + long writeRequests = 0; + for (Address server : rsGroupInfo.getServers()) { + ServerMetrics sl = collectServers.get(server); + if (sl != null) { + for (RegionMetrics rm : sl.getRegionMetrics().values()) { + readRequests += rm.getReadRequestCount(); + writeRequests += rm.getWriteRequestCount(); + } + requestsPerSecond += sl.getRequestCountPerSecond(); + } + } + %> + + + + + + + <% + } + %> +
RSGroup NameRequest Per SecondRead Request CountWrite Request Count
<%= rsGroupLink(rsGroupName) %><%= requestsPerSecond %><%= readRequests %><%= writeRequests %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_storeStats.jsp b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_storeStats.jsp new file mode 100644 index 000000000000..4614d95ada22 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/rsGroupList_storeStats.jsp @@ -0,0 +1,108 @@ +<%-- +/** +* 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. +*/ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.Map" + import="org.apache.hadoop.hbase.ServerMetrics" + import="org.apache.hadoop.hbase.net.Address" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix" %> +<%@ page import="org.apache.hadoop.hbase.RegionMetrics" %> +<%@ page import="org.apache.hadoop.hbase.Size" %> + +<%! + // TODO: Extract to common place! + private static String rsGroupLink(String rsGroupName) { + return "" + rsGroupName + ""; + } +%> + +<% + RSGroupInfo [] rsGroupInfos = (RSGroupInfo[]) request.getAttribute("rsGroupInfos"); // TODO: intro constant! + Map collectServers = (Map) request.getAttribute("collectServers"); // TODO: intro constant! +%> + + + + + + + + + + + + <% + final String ZEROKB = "0 KB"; + final String ZEROMB = "0 MB"; + for (RSGroupInfo rsGroupInfo: rsGroupInfos) { + String uncompressedStorefileSizeStr = ZEROMB; + String storefileSizeStr = ZEROMB; + String indexSizeStr = ZEROKB; + String bloomSizeStr = ZEROKB; + String rsGroupName = rsGroupInfo.getName(); + int numStores = 0; + long numStorefiles = 0; + long uncompressedStorefileSize = 0; + long storefileSize = 0; + long indexSize = 0; + long bloomSize = 0; + for (Address server : rsGroupInfo.getServers()) { + ServerMetrics sl = collectServers.get(server); + if (sl != null) { + for (RegionMetrics rm : sl.getRegionMetrics().values()) { + numStores += rm.getStoreCount(); + numStorefiles += rm.getStoreFileCount(); + uncompressedStorefileSize += rm.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE); + storefileSize += rm.getStoreFileSize().get(Size.Unit.MEGABYTE); + indexSize += rm.getStoreFileUncompressedDataIndexSize().get(Size.Unit.KILOBYTE); + bloomSize += rm.getBloomFilterSize().get(Size.Unit.KILOBYTE); + } + } + } + if (uncompressedStorefileSize > 0) { + uncompressedStorefileSizeStr = TraditionalBinaryPrefix. + long2String(uncompressedStorefileSize * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } + if (storefileSize > 0) { + storefileSizeStr = TraditionalBinaryPrefix. + long2String(storefileSize * TraditionalBinaryPrefix.MEGA.value, "B", 1); + } + if (indexSize > 0) { + indexSizeStr = TraditionalBinaryPrefix. + long2String(indexSize * TraditionalBinaryPrefix.KILO.value, "B", 1); + } + if (bloomSize > 0) { + bloomSizeStr = TraditionalBinaryPrefix. + long2String(bloomSize * TraditionalBinaryPrefix.KILO.value, "B", 1); + } +%> + + + + + + + + + +<% +} +%> +
RSGroup NameNum. StoresNum. StorefilesStorefile Size UncompressedStorefile SizeIndex SizeBloom Size
<%= rsGroupLink(rsGroupName) %><%= numStores %><%= numStorefiles %><%= uncompressedStorefileSizeStr %><%= storefileSizeStr %><%= indexSizeStr %><%= bloomSizeStr %>
From 1c14a797e73cf9b9ecbcb2030d9d1b034da2d6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Fri, 28 Mar 2025 14:51:13 +0100 Subject: [PATCH 04/31] HBASE-29223 User tables --- .../resources/hbase-webapps/master/master.jsp | 56 +++++++- .../hbase-webapps/master/userTables.jsp | 133 ++++++++++++++++++ 2 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/userTables.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index 4aee9814011f..0fc3142deb1e 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -42,13 +42,11 @@ import="org.apache.hadoop.hbase.security.visibility.VisibilityConstants" import="org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotDescription" import="org.apache.hadoop.hbase.tool.CanaryTool" - import="org.apache.hadoop.hbase.util.Bytes" - import="org.apache.hadoop.hbase.util.CommonFSUtils" - import="org.apache.hadoop.hbase.util.JvmVersion" - import="org.apache.hadoop.hbase.util.PrettyPrinter" import="org.apache.hadoop.util.StringUtils" import="org.apache.hadoop.hbase.master.assignment.RegionStateNode" - import="org.apache.hadoop.hbase.client.*" %> + import="org.apache.hadoop.hbase.client.*" + import="org.apache.hadoop.conf.Configuration" + import="org.apache.hadoop.hbase.util.*" %> <%! private static ServerName getMetaLocationOrNull(HMaster master) { RegionStateNode rsn = master.getAssignmentManager().getRegionStates() @@ -58,9 +56,23 @@ } return null; } + + private Map getFragmentationInfo(HMaster master, Configuration conf) + throws IOException { + boolean showFragmentation = conf.getBoolean("hbase.master.ui.fragmentation.enabled", false); + if (showFragmentation) { + return FSUtils.getTableFragmentation(master); + } else { + return null; + } + } %> <% HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + + Configuration conf = master.getConfiguration(); + Map frags = getFragmentationInfo(master, conf); + String title; if(master.isActiveMaster()) { title = "Master: "; @@ -170,6 +182,40 @@ +
+
+

Tables

+
+ +
+
+ <%if (metaLocation != null) { %> + <% request.setAttribute("frags", frags); %> + + <% } %> +
+
+ <%if (metaLocation != null) { %> + TODO! + <& catalogTables &> + <% } %> +
+
+
+
+
+
+
TODO diff --git a/hbase-server/src/main/resources/hbase-webapps/master/userTables.jsp b/hbase-server/src/main/resources/hbase-webapps/master/userTables.jsp new file mode 100644 index 000000000000..41e246239cb4 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/userTables.jsp @@ -0,0 +1,133 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.*" + import="java.net.URLEncoder" + import="java.io.IOException" + import="org.apache.hadoop.hbase.TableName" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.master.RegionState" + import="org.apache.hadoop.hbase.client.*" %> +<%! + public static String getUserTables(HMaster master, List tables){ + if (master.isInitialized()){ + try { + Map descriptorMap = master.getTableDescriptors().getAll(); + if (descriptorMap != null) { + for (TableDescriptor desc : descriptorMap.values()) { + if (!desc.getTableName().isSystemTable()) { + tables.add(desc); + } + } + } + } catch (IOException e) { + return "Got user tables error, " + e.getMessage(); + } + } + return null; + } +%> + +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + + Map frags = (Map) request.getAttribute("frags"); // TODO: intro constant! + + List tables = new ArrayList<>(); + String errorMessage = getUserTables(master, tables); +%> + +<% if (tables.size() == 0 && errorMessage != null) { %> +

<%= errorMessage %>

+<% } %> + +<% if (tables != null && tables.size() > 0) { %> + + + + + + <% if (frags != null) { %> + + <% } %> + + + + + + + + + + + + + + + + <% for (TableDescriptor desc : tables) { %> + <% + TableName tableName = desc.getTableName(); + TableState tableState = master.getTableStateManager().getTableState(tableName); + Map> tableRegions = + master.getAssignmentManager().getRegionStates() + .getRegionByStateOfTable(tableName); + int openRegionsCount = tableRegions.get(RegionState.State.OPEN).size(); + int openingRegionsCount = tableRegions.get(RegionState.State.OPENING).size(); + int closedRegionsCount = tableRegions.get(RegionState.State.CLOSED).size(); + int closingRegionsCount = tableRegions.get(RegionState.State.CLOSING).size(); + int offlineRegionsCount = tableRegions.get(RegionState.State.OFFLINE).size(); + int splitRegionsCount = tableRegions.get(RegionState.State.SPLIT).size(); + int otherRegionsCount = 0; + for (List list: tableRegions.values()) { + otherRegionsCount += list.size(); + } + // now subtract known states + otherRegionsCount = otherRegionsCount - openRegionsCount + - offlineRegionsCount - splitRegionsCount + - openingRegionsCount - closedRegionsCount + - closingRegionsCount; + String encodedTableName = URLEncoder.encode(tableName.getNameAsString()); + %> + + + <% if (tableState.isDisabledOrDisabling()) { %> <% } else { %> <% } %> + <% if (frags != null) { %> + + <% } %> + <% if (tableState.isDisabledOrDisabling()) { %> <% } else { %> <% } %> + + <% if (openingRegionsCount > 0) { %> <% } else { %> <% } %> + <% if (closedRegionsCount > 0) { %> <% } else { %> <% } %> + <% if (closingRegionsCount > 0) { %> <% } else { %> <% } %> + <% if (offlineRegionsCount > 0) { %> <% } else { %> <% } %> + <% if (splitRegionsCount > 0) { %> <% } else { %> <% } %> + + + +<% } %> +

<%= tables.size() %> table(s) in set. [Details]. Click count below to + see list of regions currently in 'state' designated by the column title. For 'Other' Region state, + browse to hbase:meta and adjust filter on 'Meta Entries' to + query on states other than those listed here. Queries may take a while if the hbase:meta table + is large.

+ +
NamespaceNameFrag.StateRegionsDescription
OPENOPENINGCLOSEDCLOSINGOFFLINESPLITOther
<%= tableName.getNamespaceAsString() %>><%= URLEncoder.encode(tableName.getQualifierAsString()) %>><%= URLEncoder.encode(tableName.getQualifierAsString()) %><%= frags.get(tableName.getNameAsString()) != null ? frags.get(tableName.getNameAsString()).intValue() + "%" : "n/a" %><%= tableState.getState().name() %><%= tableState.getState() %><%= openRegionsCount %><%= openingRegionsCount %><%= openingRegionsCount %><%= closedRegionsCount %><%= closedRegionsCount %><%= closingRegionsCount %><%= closingRegionsCount %><%= offlineRegionsCount %><%= offlineRegionsCount %><%= splitRegionsCount %><%= splitRegionsCount %><%= otherRegionsCount %><%= desc.toStringCustomizedValues() %>
+<% } %> From 92010c1b051be0c053e571c588a37a7f33477597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Fri, 28 Mar 2025 15:08:21 +0100 Subject: [PATCH 05/31] HBASE-29223 System (catalog) tables --- .../hbase-webapps/master/catalogTables.jsp | 81 +++++++++++++++++++ .../resources/hbase-webapps/master/master.jsp | 5 +- 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/catalogTables.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/catalogTables.jsp b/hbase-server/src/main/resources/hbase-webapps/master/catalogTables.jsp new file mode 100644 index 000000000000..3a80741f209c --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/catalogTables.jsp @@ -0,0 +1,81 @@ +<%-- +/** + * 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. + */ +--%> + +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.*" + import="org.apache.hadoop.hbase.NamespaceDescriptor" + import="org.apache.hadoop.hbase.TableName" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.quotas.QuotaUtil" + import="org.apache.hadoop.hbase.security.access.PermissionStorage" + import="org.apache.hadoop.hbase.security.visibility.VisibilityConstants" + import="org.apache.hadoop.hbase.tool.CanaryTool" + import="org.apache.hadoop.hbase.client.*" %> + +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + + Map frags = (Map) request.getAttribute("frags"); // TODO: intro constant! + + List sysTables = master.isInitialized() ? + master.listTableDescriptorsByNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR) : null; +%> + +<%if (sysTables != null && sysTables.size() > 0) { %> + + + + <% if (frags != null) { %> + + <% } %> + + + <% for (TableDescriptor systemTable : sysTables) { %> + + <% TableName tableName = systemTable.getTableName();%> + + <% if (frags != null) { %> + + <% } %> + <% String description = null; + if (tableName.equals(TableName.META_TABLE_NAME)){ + description = "The hbase:meta table holds references to all User Table regions."; + } else if (tableName.equals(CanaryTool.DEFAULT_WRITE_TABLE_NAME)){ + description = "The hbase:canary table is used to sniff the write availbility of" + + " each regionserver."; + } else if (tableName.equals(PermissionStorage.ACL_TABLE_NAME)){ + description = "The hbase:acl table holds information about acl."; + } else if (tableName.equals(VisibilityConstants.LABELS_TABLE_NAME)){ + description = "The hbase:labels table holds information about visibility labels."; + } else if (tableName.equals(QuotaUtil.QUOTA_TABLE_NAME)){ + description = "The hbase:quota table holds quota information about number" + + " or size of requests in a given time frame."; + } else if (tableName.equals(TableName.valueOf("hbase:rsgroup"))){ + description = "The hbase:rsgroup table holds information about regionserver groups."; + } else if (tableName.equals(TableName.valueOf("hbase:replication"))) { + description = "The hbase:replication table tracks cross cluster replication through " + + "WAL file offsets."; + } + %> + + + <% } %> +
Table NameFrag.Description
<%= tableName %><%= frags.get(tableName.getNameAsString()) != null ? frags.get(tableName.getNameAsString()) + "%" : "n/a" %><%= description %>
+<% } %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index 0fc3142deb1e..f189a19cce3d 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -206,11 +206,12 @@
<%if (metaLocation != null) { %> - TODO! - <& catalogTables &> + <% request.setAttribute("frags", frags); %> + <% } %>
+ <%-- tab.js will load userSnapshots.jsp with an AJAX request here. --%>
From 5aea1605015595b6bf238e8e32b5084fd0618a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Fri, 28 Mar 2025 15:51:08 +0100 Subject: [PATCH 06/31] HBASE-29223 Region Visualizer, Peers --- .../resources/hbase-webapps/master/master.jsp | 12 ++ .../hbase-webapps/master/peerConfigs.jsp | 86 +++++++++++++ .../hbase-webapps/master/regionVisualizer.jsp | 120 ++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/peerConfigs.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/regionVisualizer.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index f189a19cce3d..9eefd45974cd 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -217,6 +217,18 @@ +
+
+

Region Visualizer

+ +
+
+
+
+

Peers

+ +
+
TODO diff --git a/hbase-server/src/main/resources/hbase-webapps/master/peerConfigs.jsp b/hbase-server/src/main/resources/hbase-webapps/master/peerConfigs.jsp new file mode 100644 index 000000000000..2cc14b032c2b --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/peerConfigs.jsp @@ -0,0 +1,86 @@ +<%-- +/** + * 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. + */ +--%> + +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.*" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.replication.ReplicationPeerDescription" + import="org.apache.hadoop.hbase.replication.ReplicationPeerConfig" + import="org.apache.hadoop.hbase.client.replication.ReplicationPeerConfigUtil" + import="org.apache.hadoop.hbase.util.Strings" %> + +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + + List peers = null; + if (master.getReplicationPeerManager() != null) { + peers = master.getReplicationPeerManager().listPeers(null); + } +%> + + + + + + + + + + + + + + + + +<% if (peers != null && peers.size() > 0) { %> + <% for (ReplicationPeerDescription peer : peers) { %> + <% + String peerId = peer.getPeerId(); + ReplicationPeerConfig peerConfig = peer.getPeerConfig(); + %> + + + + + + + + + + + + + + <% } %> +<% } %> + + +
Peer IdCluster KeyEndpointStateIsSerialRemote WALSync Replication StateBandwidthReplicateAllNamespacesExclude NamespacesTable CfsExclude Table Cfs
<%= peerId %><%= peerConfig.getClusterKey() %><%= peerConfig.getReplicationEndpointImpl() %><%= peer.isEnabled() ? "ENABLED" : "DISABLED" %><%= peerConfig.isSerial() %><%= peerConfig.getRemoteWALDir() == null ? "" : peerConfig.getRemoteWALDir() %> + <%= peer.getSyncReplicationState() %> + <%= peerConfig.getBandwidth() == 0? "UNLIMITED" : Strings.humanReadableInt(peerConfig.getBandwidth()) %><%= peerConfig.replicateAllUserTables() %> + <%= peerConfig.getNamespaces() == null ? "" : ReplicationPeerConfigUtil.convertToString(peerConfig.getNamespaces()).replaceAll(";", "; ") %> + + <%= peerConfig.getExcludeNamespaces() == null ? "" : ReplicationPeerConfigUtil.convertToString(peerConfig.getExcludeNamespaces()).replaceAll(";", "; ") %> + + <%= peerConfig.getTableCFsMap() == null ? "" : ReplicationPeerConfigUtil.convertToString(peerConfig.getTableCFsMap()).replaceAll(";", "; ") %> + + <%= peerConfig.getExcludeTableCFsMap() == null ? "" : ReplicationPeerConfigUtil.convertToString(peerConfig.getExcludeTableCFsMap()).replaceAll(";", "; ") %> +
Total: <%= (peers != null) ? peers.size() : 0 %>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/regionVisualizer.jsp b/hbase-server/src/main/resources/hbase-webapps/master/regionVisualizer.jsp new file mode 100644 index 000000000000..d75b2382d322 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/regionVisualizer.jsp @@ -0,0 +1,120 @@ +<%-- +/** + * 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. + */ +--%> + + + + + +
+ From 95c7c1c6aba3747956d8172390d546084e9e718c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Mon, 31 Mar 2025 09:46:54 +0200 Subject: [PATCH 07/31] HBASE-29223 Tasks section + JSON task output --- .../resources/hbase-webapps/master/master.jsp | 24 ++++- .../hbase-webapps/master/taskMonitor.jsp | 89 +++++++++++++++++++ .../master/taskMonitor_renderTasks.jsp | 86 ++++++++++++++++++ 3 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/taskMonitor.jsp create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/taskMonitor_renderTasks.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index 9eefd45974cd..d69c9f64a3ff 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -47,6 +47,20 @@ import="org.apache.hadoop.hbase.client.*" import="org.apache.hadoop.conf.Configuration" import="org.apache.hadoop.hbase.util.*" %> + +<% + String filter = request.getParameter("filter"); + String format = request.getParameter("format"); + if (format != null && format.equals("json")) { + request.setAttribute("filter", filter); + request.setAttribute("format", "json"); + %> + +<% + return; + } +%> + <%! private static ServerName getMetaLocationOrNull(HMaster master) { RegionStateNode rsn = master.getAssignmentManager().getRegionStates() @@ -229,10 +243,18 @@ +<% } else { %> +
+ +
+<% } %> + +
+ +
TODO - <% } %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/taskMonitor.jsp b/hbase-server/src/main/resources/hbase-webapps/master/taskMonitor.jsp new file mode 100644 index 000000000000..9a5653012242 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/taskMonitor.jsp @@ -0,0 +1,89 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" %> + +<% + String filter = (String) request.getAttribute("filter"); // TODO: intro constant! + if (filter == null) { + filter = "general"; + } + String format = (String) request.getAttribute("format"); // TODO: intro constant! + if (format == null) { + format = "html"; + } + String parent = (String) request.getAttribute("parent"); // TODO: intro constant! + if (parent == null) { + parent = ""; + } +%> + +<% if (format.equals("json")) { %> + <% request.setAttribute("filter", filter); %> + +<% } else { %> +

Tasks

+ +
+ +
+
+ View as JSON + <% request.setAttribute("filter", "all"); %> + +
+
+ View as JSON + <% request.setAttribute("filter", "general"); %> + +
+
+ View as JSON + <% request.setAttribute("filter", "handler"); %> + +
+
+ View as JSON + <% request.setAttribute("filter", "rpc"); %> + +
+
+ View as JSON + <% request.setAttribute("filter", "operation"); %> + +
+
+
+<% } %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/taskMonitor_renderTasks.jsp b/hbase-server/src/main/resources/hbase-webapps/master/taskMonitor_renderTasks.jsp new file mode 100644 index 000000000000..1924d92123df --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/taskMonitor_renderTasks.jsp @@ -0,0 +1,86 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.*" + import="org.apache.hadoop.hbase.monitoring.*" + import="org.apache.hadoop.util.StringUtils" %> + +<%! + public static String stateCss(MonitoredTask.State state) { + if (state == MonitoredTask.State.COMPLETE) { + return "alert alert-success"; + } else if (state == MonitoredTask.State.ABORTED) { + return "alert alert-danger"; + } else { + return ""; + } + } +%> + +<% + TaskMonitor taskMonitor = TaskMonitor.get(); + String filter = (String) request.getAttribute("filter"); // TODO: intro constant! + String format = (String) request.getAttribute("format"); // TODO: intro constant! + if (format == null) { + format = "html"; + } + + List tasks = taskMonitor.getTasks(filter); + long now = System.currentTimeMillis(); + Collections.sort(tasks, (t1, t2) -> Long.compare(t1.getStateTime(), t2.getStateTime())); + boolean first = true; + %> + +<% if (format.equals("json")) { %> +[<% for (MonitoredTask task : tasks) { %><% if (first) { %><% first = false;%><% } else { %>,<% } %><%= task.toJSON() %><% } %>] +<% } else { %> + <% if (tasks.isEmpty()) { %> +

No tasks currently running on this node.

+ <% } else { %> + + + + + + + + + <% for (MonitoredTask task : tasks) { %> + + + + + + + + <% } %> +
Start TimeDescriptionStateStatusCompletion Time
<%= new Date(task.getStartTime()) %><%= task.getDescription() %><%= task.getState() %> + (since <%= StringUtils.formatTimeDiff(now, task.getStateTime()) %> ago) + <%= task.getStatus() %> + (since <%= StringUtils.formatTimeDiff(now, task.getStatusTime()) %> + ago) + <% if (task.getCompletionTimestamp() < 0) { %> + <%= task.getState() %> + <% } else { %> + <%= new Date(task.getCompletionTimestamp()) %> (since <%= StringUtils.formatTimeDiff(now, task.getCompletionTimestamp()) %> ago) + <% } %> +
+ <% } %> +<% } %> From 9687fee9f281656904447f74f4b9413f2f558159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Mon, 31 Mar 2025 13:18:03 +0200 Subject: [PATCH 08/31] HBASE-29223 Software Attributes section --- .../resources/hbase-webapps/master/master.jsp | 10 + .../master/softwareAttributes.jsp | 172 ++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/softwareAttributes.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index d69c9f64a3ff..0324a6d4c1e1 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -253,8 +253,18 @@ +
+ <% request.setAttribute("frags", frags); %> + +
+ TODO + + + + + diff --git a/hbase-server/src/main/resources/hbase-webapps/master/softwareAttributes.jsp b/hbase-server/src/main/resources/hbase-webapps/master/softwareAttributes.jsp new file mode 100644 index 000000000000..1063b38370fd --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/softwareAttributes.jsp @@ -0,0 +1,172 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="java.util.*" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.util.JvmVersion" + import="org.apache.hadoop.hbase.util.CommonFSUtils" + import="org.apache.hadoop.util.StringUtils" %> + +<%! + public static String formatZKString(HMaster master) { + StringBuilder quorums = new StringBuilder(); + String zkQuorum = master.getZooKeeper().getQuorum(); + + if (null == zkQuorum) { + return quorums.toString(); + } + + String[] zks = zkQuorum.split(","); + + if (zks.length == 0) { + return quorums.toString(); + } + + for(int i = 0; i < zks.length; ++i) { + quorums.append(zks[i].trim()); + + if (i != (zks.length - 1)) { + quorums.append("
"); + } + } + + return quorums.toString(); + } +%> + +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + + Map frags = (Map) request.getAttribute("frags"); // TODO: intro constant! +%> + +

Software Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <% if (master.isActiveMaster()) { %> + + + + + + + + + + + + + + + + <% if (frags != null) { %> + + + + + + <% } %> + + + + + + + + + + + <% } %> +
Attribute NameValueDescription
JVM Version<%= JvmVersion.getVersion() %>JVM vendor and version
HBase Version<%= org.apache.hadoop.hbase.util.VersionInfo.getVersion() %>, revision=<%= org.apache.hadoop.hbase.util.VersionInfo.getRevision() %>HBase version and revision
HBase Compiled<%= org.apache.hadoop.hbase.util.VersionInfo.getDate() %>, <%= org.apache.hadoop.hbase.util.VersionInfo.getUser() %>When HBase version was compiled and by whom
HBase Source Checksum<%= org.apache.hadoop.hbase.util.VersionInfo.getSrcChecksum() %>HBase source SHA512 checksum
Hadoop Version<%= org.apache.hadoop.util.VersionInfo.getVersion() %>, revision=<%= org.apache.hadoop.util.VersionInfo.getRevision() %>Hadoop version and revision
Hadoop Compiled<%= org.apache.hadoop.util.VersionInfo.getDate() %>, <%= org.apache.hadoop.util.VersionInfo.getUser() %>When Hadoop version was compiled and by whom
Hadoop Source Checksum<%= org.apache.hadoop.util.VersionInfo.getSrcChecksum() %>Hadoop source MD5 checksum
ZooKeeper Client Version<%= org.apache.zookeeper.Version.getVersion() %>, revision=<%= org.apache.zookeeper.Version.getRevisionHash() %>ZooKeeper client version and revision hash
ZooKeeper Client Compiled<%= org.apache.zookeeper.Version.getBuildDate() %>When ZooKeeper client version was compiled
ZooKeeper Quorum <%= formatZKString(master) %> Addresses of all registered ZK servers. For more, see zk dump.
ZooKeeper Base Path <%= master.getZooKeeper().getZNodePaths().baseZNode %>Root node of this cluster in ZK.
Cluster Key <%= formatZKString(master) %>:<%= master.getZooKeeper().getZNodePaths().baseZNode %>Key to add this cluster as a peer for replication. Use 'help "add_peer"' in the shell for details.
HBase Root Directory<%= CommonFSUtils.getRootDir(master.getConfiguration()).toString() %>Location of HBase home directory
HMaster Start Time<%= new Date(master.getMasterStartTime()) %>Date stamp of when this HMaster was started
HMaster Active Time<%= new Date(master.getMasterActiveTime()) %>Date stamp of when this HMaster became active
HBase Cluster ID<%= master.getClusterId() != null ? master.getClusterId() : "Not set" %>Unique identifier generated for each HBase cluster
Load average<%= master.getServerManager() == null ? "0.00" : + StringUtils.limitDecimalTo2(master.getServerManager().getAverageLoad()) %>Average number of regions per regionserver. Naive computation.
Fragmentation<%= frags.get("-TOTAL-") != null ? frags.get("-TOTAL-") + "%" : "n/a" %>Overall fragmentation of all tables, including hbase:meta
Coprocessors<%= master.getMasterCoprocessorHost() == null ? "[]" : + java.util.Arrays.toString(master.getMasterCoprocessors()) %>Coprocessors currently loaded by the master
LoadBalancer<%= master.getLoadBalancerClassName() %>LoadBalancer to be used in the Master
From cb63fe0ea66fb2307ccfa30ab5c242094f96eabb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Mon, 31 Mar 2025 13:27:51 +0200 Subject: [PATCH 09/31] HBASE-29223 Cleanup master.jsp, moved getting dead servers into deadRegionServers.jsp --- .../master/deadRegionServers.jsp | 22 ++- .../resources/hbase-webapps/master/master.jsp | 32 +---- .../static/js/masterStatusInit.js | 126 ++++++++++++++++++ 3 files changed, 144 insertions(+), 36 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/static/js/masterStatusInit.js diff --git a/hbase-server/src/main/resources/hbase-webapps/master/deadRegionServers.jsp b/hbase-server/src/main/resources/hbase-webapps/master/deadRegionServers.jsp index 7de91db80f4b..436801f544af 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/deadRegionServers.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/deadRegionServers.jsp @@ -20,14 +20,24 @@ <%@ page contentType="text/html;charset=UTF-8" import="org.apache.hadoop.hbase.ServerName" import="java.util.*" - import="org.apache.hadoop.hbase.master.HMaster" %> -<%@ page import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" %> -<%@ page import="org.apache.hadoop.hbase.rsgroup.RSGroupInfoManager" %> -<%@ page import="org.apache.hadoop.hbase.master.DeadServer" %> -<%@ page import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" %> + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfoManager" + import="org.apache.hadoop.hbase.master.DeadServer" + import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" + import="org.apache.hadoop.hbase.master.ServerManager" %> <% - Set deadServers = (Set) request.getAttribute("deadServers"); // TODO: intro constant! HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + + ServerManager serverManager = master.getServerManager(); + + Set deadServers = null; + + if (master.isActiveMaster()) { + if (serverManager != null) { + deadServers = serverManager.getDeadServers().copyServerNames(); + } + } %> <% if (deadServers != null && deadServers.size() > 0) { %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index 0324a6d4c1e1..32e9b36158a3 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -19,30 +19,12 @@ --%> <%@ page contentType="text/html;charset=UTF-8" import="java.util.*" - import="java.net.URLEncoder" import="java.io.IOException" - import="org.apache.hadoop.hbase.client.replication.ReplicationPeerConfigUtil" - import="org.apache.hadoop.hbase.replication.ReplicationPeerConfig" - import="org.apache.hadoop.hbase.replication.ReplicationPeerDescription" - import="org.apache.hadoop.hbase.HBaseConfiguration" - import="org.apache.hadoop.hbase.HConstants" - import="org.apache.hadoop.hbase.NamespaceDescriptor" import="org.apache.hadoop.hbase.ServerName" - import="org.apache.hadoop.hbase.TableName" - import="org.apache.hadoop.hbase.master.assignment.AssignmentManager" - import="org.apache.hadoop.hbase.master.DeadServer" import="org.apache.hadoop.hbase.master.HMaster" import="org.apache.hadoop.hbase.master.RegionState" import="org.apache.hadoop.hbase.master.ServerManager" - import="org.apache.hadoop.hbase.quotas.QuotaUtil" - import="org.apache.hadoop.hbase.rsgroup.RSGroupInfoManager" - import="org.apache.hadoop.hbase.rsgroup.RSGroupInfo" import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" - import="org.apache.hadoop.hbase.security.access.PermissionStorage" - import="org.apache.hadoop.hbase.security.visibility.VisibilityConstants" - import="org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotDescription" - import="org.apache.hadoop.hbase.tool.CanaryTool" - import="org.apache.hadoop.util.StringUtils" import="org.apache.hadoop.hbase.master.assignment.RegionStateNode" import="org.apache.hadoop.hbase.client.*" import="org.apache.hadoop.conf.Configuration" @@ -100,15 +82,9 @@ ServerManager serverManager = master.getServerManager(); ServerName metaLocation = null; - List servers = null; - Set deadServers = null; if (master.isActiveMaster()) { metaLocation = getMetaLocationOrNull(master); - if (serverManager != null) { - deadServers = serverManager.getDeadServers().copyServerNames(); - servers = serverManager.getOnlineServersList(); - } } %> @@ -185,10 +161,7 @@

Region Servers

- <% if (deadServers != null) { %> - <% request.setAttribute("deadServers", deadServers); %> - - <% } %> +
@@ -258,8 +231,6 @@ - TODO -
@@ -268,3 +239,4 @@ + diff --git a/hbase-server/src/main/resources/hbase-webapps/static/js/masterStatusInit.js b/hbase-server/src/main/resources/hbase-webapps/static/js/masterStatusInit.js new file mode 100644 index 000000000000..0b09b6ee06b9 --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/static/js/masterStatusInit.js @@ -0,0 +1,126 @@ +/* + * Copyright The Apache Software Foundation + * + * 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. + */ + +$(document).ready(function() + { + $.tablesorter.addParser( + { + id: 'filesize', + is: function(s) { + return s.match(new RegExp( /([\.0-9]+)\ (B|KB|MB|GB|TB)/ )); + }, + format: function(s) { + var suf = s.match(new RegExp( /(KB|B|GB|MB|TB)$/ ))[1]; + var num = parseFloat(s.match( new RegExp( /([\.0-9]+)\ (B|KB|MB|GB|TB)/ ))[0]); + switch(suf) { + case 'B': + return num; + case 'KB': + return num * 1024; + case 'MB': + return num * 1024 * 1024; + case 'GB': + return num * 1024 * 1024 * 1024; + case 'TB': + return num * 1024 * 1024 * 1024 * 1024; + } + }, + type: 'numeric' + }); + $.tablesorter.addParser( + { + id: "separator", + is: function (s) { + return /^[0-9]?[0-9,]*$/.test(s); + }, format: function (s) { + return $.tablesorter.formatFloat( s.replace(/,/g,'') ); + }, type: "numeric" + }); + $.tablesorter.addParser( + { + id: "dateTime", + is: function (s) { + return /^([a-zA-Z]{3}\s){2}\d{2}\s\d{2}:\d{2}:\d{2}\s[a-zA-Z]{3}\s\d{4}$/.test(s); + }, format: function (s) { + var split = s.split(" "); + var time = Date.parse(split[1] + " " + split[2] + " " + split[3] + " " + split[5]); + return $.tablesorter.formatFloat(time); + }, type: "numeric" + }); + $("#baseStatsTable").tablesorter({ + headers: { + '.cls_dateTime': {sorter: 'dateTime'}, + '.cls_separator': {sorter: 'separator'} + } + }); + $("#memoryStatsTable").tablesorter({ + headers: { + '.cls_filesize': {sorter: 'filesize'} + } + }); + $("#requestStatsTable").tablesorter({ + headers: { + '.cls_separator': {sorter: 'separator'} + } + }); + $("#storeStatsTable").tablesorter({ + headers: { + '.cls_separator': {sorter: 'separator'}, + '.cls_filesize': {sorter: 'filesize'} + } + }); + $("#compactionStatsTable").tablesorter({ + headers: { + '.cls_separator': {sorter: 'separator'} + } + }); + + $("#userTables").tablesorter(); + + function showRitPages() { + if (!$("#rit_page_num")) { + return; + } + var ritTotalNum = parseInt($("#rit_page_num").val()); + if (!ritTotalNum || ritTotalNum < 1) { + return; + } + var ritPerPage = parseInt($("#rit_per_page").val()); + + $("#rit_pagination").sPage({ + page:1, + total:ritTotalNum, + pageSize:ritPerPage, + noData: false, + showPN:true, + prevPage:"prev", + nextPage:"next", + fastForward: 5, + backFun:function(page){ + $("div[id^='tab_rits']").removeClass('active'); + $("#tab_rits"+page).addClass('active'); + } + }); + + } + showRitPages(); + + } +); From e0374ae839ff212688ca1571b1f07b5329483fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Mon, 31 Mar 2025 17:39:10 +0200 Subject: [PATCH 10/31] HBASE-29223 Warnings to separate jsp --- .../resources/hbase-webapps/master/master.jsp | 60 +------------ .../hbase-webapps/master/warnings.jsp | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+), 59 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/master/warnings.jsp diff --git a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp index 32e9b36158a3..37f1edc92e69 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/master.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/master.jsp @@ -23,8 +23,6 @@ import="org.apache.hadoop.hbase.ServerName" import="org.apache.hadoop.hbase.master.HMaster" import="org.apache.hadoop.hbase.master.RegionState" - import="org.apache.hadoop.hbase.master.ServerManager" - import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" import="org.apache.hadoop.hbase.master.assignment.RegionStateNode" import="org.apache.hadoop.hbase.client.*" import="org.apache.hadoop.conf.Configuration" @@ -78,9 +76,6 @@ title += master.getServerName().getHostname(); pageContext.setAttribute("pageTitle", title); - boolean catalogJanitorEnabled = master.isCatalogJanitorEnabled(); - ServerManager serverManager = master.getServerManager(); - ServerName metaLocation = null; if (master.isActiveMaster()) { @@ -101,60 +96,7 @@
- - <% if(JvmVersion.isBadJvmVersion()) { %> - - <% } %> - <% if(master.isInitialized() && !catalogJanitorEnabled) { %> - - <% } %> - <% if(master.isInMaintenanceMode()) { %> - - <% } %> - <% if(!master.isBalancerOn()) { %> - - <% } %> - <% if(!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) { %> - - <% } %> - <% if(!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) { %> - - <% } %> - <% if(master.getAssignmentManager() != null) { %> - - <% } %> - <% if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null) { %> - <% if (RSGroupUtil.isRSGroupEnabled(master.getConfiguration()) && - serverManager.getOnlineServersList().size() > 0) { %> -
-

RSGroup

- -
- <% } %> - <% } %> +
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/warnings.jsp b/hbase-server/src/main/resources/hbase-webapps/master/warnings.jsp new file mode 100644 index 000000000000..b0044c97f45d --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/master/warnings.jsp @@ -0,0 +1,87 @@ +<%-- +/** + * 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. + */ +--%> +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.rsgroup.RSGroupUtil" + import="org.apache.hadoop.hbase.master.ServerManager" + import="org.apache.hadoop.hbase.util.JvmVersion" + import="org.apache.hadoop.hbase.client.MasterSwitchType" %> + +<% + HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); + + boolean catalogJanitorEnabled = master.isCatalogJanitorEnabled(); + ServerManager serverManager = master.getServerManager(); +%> + + +<% if(JvmVersion.isBadJvmVersion()) { %> + +<% } %> +<% if(master.isInitialized() && !catalogJanitorEnabled) { %> + +<% } %> +<% if(master.isInMaintenanceMode()) { %> + +<% } %> +<% if(!master.isBalancerOn()) { %> + +<% } %> +<% if(!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) { %> + +<% } %> +<% if(!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) { %> + +<% } %> +<% if(master.getAssignmentManager() != null) { %> + +<% } %> +<% if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null) { %> + <% if (RSGroupUtil.isRSGroupEnabled(master.getConfiguration()) && + serverManager.getOnlineServersList().size() > 0) { %> +
+

RSGroup

+ +
+ <% } %> +<% } %> From 3036c492f2a854dae8bed3af11f5a552b4dbab2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Mon, 31 Mar 2025 18:03:49 +0200 Subject: [PATCH 11/31] HBASE-29223 Remove MasterStatusServlet and related Jamon page templates --- .../master/AssignmentManagerStatusTmpl.jamon | 128 --- .../tmpl/master/BackupMasterStatusTmpl.jamon | 70 -- .../hbase/tmpl/master/MasterStatusTmpl.jamon | 800 ------------------ .../hbase/tmpl/master/RSGroupListTmpl.jamon | 393 --------- .../tmpl/master/RegionServerListTmpl.jamon | 538 ------------ .../tmpl/master/RegionVisualizerTmpl.jamon | 119 --- .../apache/hadoop/hbase/master/HMaster.java | 2 - .../master/http/MasterStatusServlet.java | 95 --- .../hbase/master/http/RegionVisualizer.java | 2 +- .../hbase-webapps/master/tablesDetailed.jsp | 29 +- .../master/http/TestMasterStatusServlet.java | 152 ---- 11 files changed, 26 insertions(+), 2302 deletions(-) delete mode 100644 hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon delete mode 100644 hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/BackupMasterStatusTmpl.jamon delete mode 100644 hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RSGroupListTmpl.jamon delete mode 100644 hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionServerListTmpl.jamon delete mode 100644 hbase-server/src/main/java/org/apache/hadoop/hbase/master/http/MasterStatusServlet.java delete mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/master/http/TestMasterStatusServlet.java diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon deleted file mode 100644 index ee899a7340dc..000000000000 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon +++ /dev/null @@ -1,128 +0,0 @@ -<%doc> - -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. - -<%import> -java.util.Map; -java.util.Set; -java.util.SortedSet; -java.util.concurrent.atomic.AtomicInteger; -java.util.stream.Collectors; -org.apache.hadoop.conf.Configuration; -org.apache.hadoop.hbase.HBaseConfiguration; -org.apache.hadoop.hbase.HConstants; -org.apache.hadoop.hbase.ServerName; -org.apache.hadoop.hbase.client.RegionInfo; -org.apache.hadoop.hbase.client.RegionInfoDisplay; -org.apache.hadoop.hbase.master.RegionState; -org.apache.hadoop.hbase.master.assignment.AssignmentManager; -org.apache.hadoop.hbase.master.assignment.AssignmentManager.RegionInTransitionStat; -org.apache.hadoop.hbase.master.assignment.RegionStates.RegionFailedOpen; -org.apache.hadoop.hbase.util.Pair; - -<%args> -AssignmentManager assignmentManager; -int limit = 100; - - -<%java> -SortedSet rit = assignmentManager.getRegionStates() - .getRegionsInTransitionOrderedByTimestamp(); - - -<%if !rit.isEmpty() %> -<%java> -long currentTime = System.currentTimeMillis(); -RegionInTransitionStat ritStat = assignmentManager.computeRegionInTransitionStat(); - -int numOfRITs = rit.size(); -int ritsPerPage = Math.min(5, numOfRITs); -int numOfPages = (int) Math.ceil(numOfRITs * 1.0 / ritsPerPage); - -
-

Regions in Transition

-

<% numOfRITs %> region(s) in transition. - <%if ritStat.hasRegionsTwiceOverThreshold() %> - - <%elseif ritStat.hasRegionsOverThreshold() %> - - <%else> - - - <% ritStat.getTotalRITsOverThreshold() %> region(s) in transition for - more than <% ritStat.getRITThreshold() %> milliseconds. - -

-
-
- <%java int recordItr = 0; %> - <%for RegionState rs : rit %> - <%if (recordItr % ritsPerPage) == 0 %> - <%if recordItr == 0 %> -
- <%else> -
- - - - - - <%if ritStat.isRegionTwiceOverThreshold(rs.getRegion()) %> - - <%elseif ritStat.isRegionOverThreshold(rs.getRegion()) %> - - <%else> - - - <%java> - String retryStatus = "0"; - RegionFailedOpen regionFailedOpen = assignmentManager - .getRegionStates().getFailedOpen(rs.getRegion()); - if (regionFailedOpen != null) { - retryStatus = Integer.toString(regionFailedOpen.getRetries()); - } else if (rs.getState() == RegionState.State.FAILED_OPEN) { - retryStatus = "Failed"; - } - - - - - - <%java recordItr++; %> - <%if (recordItr % ritsPerPage) == 0 %> -
RegionStateRIT time (ms) Retries
<% rs.getRegion().getEncodedName() %> - <% RegionInfoDisplay.getDescriptiveNameFromRegionStateForDisplay(rs, - assignmentManager.getConfiguration()) %><% (currentTime - rs.getStamp()) %> <% retryStatus %>
-
- - - - <%if (recordItr % ritsPerPage) != 0 %> - <%for ; (recordItr % ritsPerPage) != 0 ; recordItr++ %> - - - -
- -
- - - -
-
- - diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/BackupMasterStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/BackupMasterStatusTmpl.jamon deleted file mode 100644 index 21af264bbe34..000000000000 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/BackupMasterStatusTmpl.jamon +++ /dev/null @@ -1,70 +0,0 @@ -<%doc> - -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. - -<%args> -HMaster master; - -<%import> -java.util.*; -org.apache.hadoop.hbase.ServerName; -org.apache.hadoop.hbase.ClusterMetrics; -org.apache.hadoop.hbase.master.HMaster; -org.apache.hbase.thirdparty.com.google.common.base.Preconditions; - -<%if (!master.isActiveMaster()) %> - <%java> - ServerName active_master = master.getActiveMaster().orElse(null); - Preconditions.checkState(active_master != null, "Failed to retrieve active master's ServerName!"); - int activeInfoPort = master.getActiveMasterInfoPort(); - -
- -
-

Current Active Master: <% active_master.getHostname() %>

-<%else> -

Backup Masters

- - - - - - - - <%java> - Collection backup_masters = master.getBackupMasters(); - ServerName [] backupServerNames = backup_masters.toArray(new ServerName[backup_masters.size()]); - Arrays.sort(backupServerNames); - for (ServerName serverName : backupServerNames) { - int infoPort = master.getBackupMasterInfoPort(serverName); - - - - - - - <%java> - } - - -
ServerNamePortStart Time
<% serverName.getHostname() %> - <% serverName.getPort() %><% new Date(serverName.getStartcode()) %>
Total:<% backupServerNames.length %>
- diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon index c80707d8c83b..e69de29bb2d1 100644 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon +++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmpl.jamon @@ -1,800 +0,0 @@ -<%doc> - -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. - -<%args> -HMaster master; -Map frags = null; -ServerName metaLocation = null; -List servers = null; -Set deadServers = null; -boolean catalogJanitorEnabled = true; -String filter = "general"; -String format = "html"; -ServerManager serverManager = null; -AssignmentManager assignmentManager = null; - -<%import> -java.util.*; -java.net.URLEncoder; -java.io.IOException; -org.apache.hadoop.hbase.client.replication.ReplicationPeerConfigUtil; -org.apache.hadoop.hbase.client.RegionInfo; -org.apache.hadoop.hbase.client.TableDescriptor; -org.apache.hadoop.hbase.replication.ReplicationPeerConfig; -org.apache.hadoop.hbase.replication.ReplicationPeerDescription; -org.apache.hadoop.hbase.HBaseConfiguration; -org.apache.hadoop.hbase.HConstants; -org.apache.hadoop.hbase.NamespaceDescriptor; -org.apache.hadoop.hbase.ServerName; -org.apache.hadoop.hbase.TableName; -org.apache.hadoop.hbase.client.Admin; -org.apache.hadoop.hbase.client.MasterSwitchType; -org.apache.hadoop.hbase.client.TableState; -org.apache.hadoop.hbase.master.assignment.AssignmentManager; -org.apache.hadoop.hbase.master.DeadServer; -org.apache.hadoop.hbase.master.HMaster; -org.apache.hadoop.hbase.master.RegionState; -org.apache.hadoop.hbase.master.ServerManager; -org.apache.hadoop.hbase.quotas.QuotaUtil; -org.apache.hadoop.hbase.rsgroup.RSGroupInfoManager; -org.apache.hadoop.hbase.rsgroup.RSGroupInfo; -org.apache.hadoop.hbase.rsgroup.RSGroupUtil; -org.apache.hadoop.hbase.security.access.PermissionStorage; -org.apache.hadoop.hbase.security.visibility.VisibilityConstants; -org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotDescription; -org.apache.hadoop.hbase.tool.CanaryTool; -org.apache.hadoop.hbase.util.Bytes; -org.apache.hadoop.hbase.util.CommonFSUtils; -org.apache.hadoop.hbase.util.JvmVersion; -org.apache.hadoop.hbase.util.PrettyPrinter; -org.apache.hadoop.util.StringUtils; -org.apache.hadoop.hbase.util.Strings; - - -<%if format.equals("json") %> - <& ../common/TaskMonitorTmpl; filter = filter; format = "json" &> - <%java return; %> - -<%java> -ServerManager serverManager = master.getServerManager(); -AssignmentManager assignmentManager = master.getAssignmentManager(); - - -<%class> - public String formatZKString() { - StringBuilder quorums = new StringBuilder(); - String zkQuorum = master.getZooKeeper().getQuorum(); - - if (null == zkQuorum) { - return quorums.toString(); - } - - String[] zks = zkQuorum.split(","); - - if (zks.length == 0) { - return quorums.toString(); - } - - for(int i = 0; i < zks.length; ++i) { - quorums.append(zks[i].trim()); - - if (i != (zks.length - 1)) { - quorums.append("
"); - } - } - - return quorums.toString(); - } - - -<%class> - public static String getUserTables(HMaster master, List tables){ - if (master.isInitialized()){ - try { - Map descriptorMap = master.getTableDescriptors().getAll(); - if (descriptorMap != null) { - for (TableDescriptor desc : descriptorMap.values()) { - if (!desc.getTableName().isSystemTable()) { - tables.add(desc); - } - } - } - } catch (IOException e) { - return "Got user tables error, " + e.getMessage(); - } - } - return null; - } - - - - - - - - <%if master.isActiveMaster() %>Master: <%else>Backup Master: </%if> - <% master.getServerName().getHostname() %> - - - - - - - - - - - -
- <%if master.isActiveMaster() %> -
- -
- -
- - <%if JvmVersion.isBadJvmVersion() %> - - - <%if master.isInitialized() && !catalogJanitorEnabled %> - - - <%if master.isInMaintenanceMode() %> - - - <%if !master.isBalancerOn() %> - - - <%if !master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT) %> - - - <%if !master.isSplitOrMergeEnabled(MasterSwitchType.MERGE) %> - - - <%if master.getAssignmentManager() != null %> - <& AssignmentManagerStatusTmpl; assignmentManager=master.getAssignmentManager()&> - - <%if !master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null %> - <%if RSGroupUtil.isRSGroupEnabled(master.getConfiguration()) && - serverManager.getOnlineServersList().size() > 0 %> -
-

RSGroup

- <& RSGroupListTmpl; master= master; serverManager= serverManager&> -
- - -
-
-
-

Region Servers

- <& RegionServerListTmpl; master= master; servers = servers &> - - <%if (deadServers != null) %> - <& deadRegionServers &> - -
-
-
-
- <& BackupMasterStatusTmpl; master = master &> -
-
-
-
-

Tables

-
- -
-
- <%if (metaLocation != null) %> - <& userTables &> - -
-
- <%if (metaLocation != null) %> - <& catalogTables &> - -
-
-
-
-
-
-
-
-
-

Region Visualizer

- <& RegionVisualizerTmpl &> -
-
-
-
-

Peers

- <& peerConfigs &> -
-
- <%else> -
- <& BackupMasterStatusTmpl; master = master &> -
- - - -
- <& ../common/TaskMonitorTmpl; filter = filter; parent = "/master-status" &> -
- -
-

Software Attributes

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <%escape #n> - - - - - - - - - - - - - - - - - - - - - - - - <%if master.isActiveMaster() %> - - - - - - - - - - - - - - - - <%if frags != null %> - - - - - - - - - - - - - - - - - -
Attribute NameValueDescription
JVM Version<% JvmVersion.getVersion() %>JVM vendor and version
HBase Version<% org.apache.hadoop.hbase.util.VersionInfo.getVersion() %>, revision=<% org.apache.hadoop.hbase.util.VersionInfo.getRevision() %>HBase version and revision
HBase Compiled<% org.apache.hadoop.hbase.util.VersionInfo.getDate() %>, <% org.apache.hadoop.hbase.util.VersionInfo.getUser() %>When HBase version was compiled and by whom
HBase Source Checksum<% org.apache.hadoop.hbase.util.VersionInfo.getSrcChecksum() %>HBase source SHA512 checksum
Hadoop Version<% org.apache.hadoop.util.VersionInfo.getVersion() %>, revision=<% org.apache.hadoop.util.VersionInfo.getRevision() %>Hadoop version and revision
Hadoop Compiled<% org.apache.hadoop.util.VersionInfo.getDate() %>, <% org.apache.hadoop.util.VersionInfo.getUser() %>When Hadoop version was compiled and by whom
Hadoop Source Checksum<% org.apache.hadoop.util.VersionInfo.getSrcChecksum() %>Hadoop source MD5 checksum
ZooKeeper Client Version<% org.apache.zookeeper.Version.getVersion() %>, revision=<% org.apache.zookeeper.Version.getRevisionHash() %>ZooKeeper client version and revision hash
ZooKeeper Client Compiled<% org.apache.zookeeper.Version.getBuildDate() %>When ZooKeeper client version was compiled
ZooKeeper Quorum <% formatZKString() %> Addresses of all registered ZK servers. For more, see zk dump.
ZooKeeper Base Path <% master.getZooKeeper().getZNodePaths().baseZNode %>Root node of this cluster in ZK.
Cluster Key <% formatZKString() %>:<% master.getZooKeeper().getZNodePaths().baseZNode %>Key to add this cluster as a peer for replication. Use 'help "add_peer"' in the shell for details.
HBase Root Directory<% CommonFSUtils.getRootDir(master.getConfiguration()).toString() %>Location of HBase home directory
HMaster Start Time<% new Date(master.getMasterStartTime()) %>Date stamp of when this HMaster was started
HMaster Active Time<% new Date(master.getMasterActiveTime()) %>Date stamp of when this HMaster became active
HBase Cluster ID<% master.getClusterId() != null ? master.getClusterId() : "Not set" %>Unique identifier generated for each HBase cluster
Load average<% master.getServerManager() == null ? "0.00" : - StringUtils.limitDecimalTo2(master.getServerManager().getAverageLoad()) %>Average number of regions per regionserver. Naive computation.
Fragmentation<% frags.get("-TOTAL-") != null ? frags.get("-TOTAL-").intValue() + "%" : "n/a" %>Overall fragmentation of all tables, including hbase:meta
Coprocessors<% master.getMasterCoprocessorHost() == null ? "[]" : - java.util.Arrays.toString(master.getMasterCoprocessors()) %>Coprocessors currently loaded by the master
LoadBalancer<% master.getLoadBalancerClassName() %>LoadBalancer to be used in the Master
-
-
-
- - - - - - - - - - - -<%def catalogTables> -<%java> - List sysTables = master.isInitialized() ? - master.listTableDescriptorsByNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR) : null; - -<%if (sysTables != null && sysTables.size() > 0)%> - - - - <%if (frags != null) %> - - - - -<%for TableDescriptor systemTable : sysTables%> - -<%java>TableName tableName = systemTable.getTableName(); - - <%if (frags != null)%> - - - <%java>String description = null; - if (tableName.equals(TableName.META_TABLE_NAME)){ - description = "The hbase:meta table holds references to all User Table regions."; - } else if (tableName.equals(CanaryTool.DEFAULT_WRITE_TABLE_NAME)){ - description = "The hbase:canary table is used to sniff the write availbility of" - + " each regionserver."; - } else if (tableName.equals(PermissionStorage.ACL_TABLE_NAME)){ - description = "The hbase:acl table holds information about acl."; - } else if (tableName.equals(VisibilityConstants.LABELS_TABLE_NAME)){ - description = "The hbase:labels table holds information about visibility labels."; - } else if (tableName.equals(QuotaUtil.QUOTA_TABLE_NAME)){ - description = "The hbase:quota table holds quota information about number" + - " or size of requests in a given time frame."; - } else if (tableName.equals(TableName.valueOf("hbase:rsgroup"))){ - description = "The hbase:rsgroup table holds information about regionserver groups."; - } else if (tableName.equals(TableName.valueOf("hbase:replication"))) { - description = "The hbase:replication table tracks cross cluster replication through " + - "WAL file offsets."; - } - - - - -
Table NameFrag.Description
<% tableName %><% frags.get(tableName.getNameAsString()) != null ? frags.get(tableName.getNameAsString()) - .intValue() + "%" : "n/a" %><% description %>
- - - -<%def userTables> -<%java> - List tables = new ArrayList(); - String errorMessage = getUserTables(master, tables); - -<%if (tables.size() == 0 && errorMessage != null)%> -

<% errorMessage %>

- - -<%if (tables != null && tables.size() > 0)%> - - - - - - <%if (frags != null) %> - - - - - - - - - - - - - - - - - - <%for TableDescriptor desc : tables%> - <%java> - TableName tableName = desc.getTableName(); - TableState tableState = master.getTableStateManager().getTableState(tableName); - Map> tableRegions = - master.getAssignmentManager().getRegionStates() - .getRegionByStateOfTable(tableName); - int openRegionsCount = tableRegions.get(RegionState.State.OPEN).size(); - int openingRegionsCount = tableRegions.get(RegionState.State.OPENING).size(); - int closedRegionsCount = tableRegions.get(RegionState.State.CLOSED).size(); - int closingRegionsCount = tableRegions.get(RegionState.State.CLOSING).size(); - int offlineRegionsCount = tableRegions.get(RegionState.State.OFFLINE).size(); - int splitRegionsCount = tableRegions.get(RegionState.State.SPLIT).size(); - int otherRegionsCount = 0; - for (List list: tableRegions.values()) { - otherRegionsCount += list.size(); - } - // now subtract known states - otherRegionsCount = otherRegionsCount - openRegionsCount - - offlineRegionsCount - splitRegionsCount - - openingRegionsCount - closedRegionsCount - - closingRegionsCount; - String encodedTableName = URLEncoder.encode(tableName.getNameAsString()); - - - - <%if (tableState.isDisabledOrDisabling()) %> <%else> - <%if (frags != null) %> - - - <%if (tableState.isDisabledOrDisabling()) %> <%else> - - <%if (openingRegionsCount > 0) %> <%else> - <%if (closedRegionsCount > 0) %> <%else> - <%if (closingRegionsCount > 0) %> <%else> - <%if (offlineRegionsCount > 0) %> <%else> - <%if (splitRegionsCount > 0) %> <%else> - - - - -

<% tables.size() %> table(s) in set. [Details]. Click count below to - see list of regions currently in 'state' designated by the column title. For 'Other' Region state, - browse to hbase:meta and adjust filter on 'Meta Entries' to - query on states other than those listed here. Queries may take a while if the hbase:meta table - is large.

- -
NamespaceNameFrag.StateRegionsDescription
OPENOPENINGCLOSEDCLOSINGOFFLINESPLITOther
<% tableName.getNamespaceAsString() %>><% URLEncoder.encode(tableName.getQualifierAsString()) %>><% URLEncoder.encode(tableName.getQualifierAsString()) %> <% frags.get(tableName.getNameAsString()) != null ? frags.get(tableName.getNameAsString()).intValue() + "%" : "n/a" %><% tableState.getState().name() %><% tableState.getState() %> <% openRegionsCount %><% openingRegionsCount %><% openingRegionsCount %> <% closedRegionsCount %><% closedRegionsCount %> <% closingRegionsCount %><% closingRegionsCount %> <% offlineRegionsCount %><% offlineRegionsCount %> <% splitRegionsCount %><% splitRegionsCount %> <% otherRegionsCount %><% desc.toStringCustomizedValues() %>
- - - - - -<%def deadRegionServers> - -<%if (deadServers != null && deadServers.size() > 0)%> -

Dead Region Servers

- - - - - - <%if !master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null %> - <%if RSGroupUtil.isRSGroupEnabled(master.getConfiguration()) %> - - - - - <%java> - RSGroupInfoManager inMgr = null; - DeadServer deadServerUtil = master.getServerManager().getDeadServers(); - ServerName [] deadServerNames = deadServers.toArray(new ServerName[deadServers.size()]); - Arrays.sort(deadServerNames); - if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null - && RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { - inMgr = master.getRSGroupInfoManager(); - } - for (ServerName deadServerName: deadServerNames) { - String rsGroupName = null; - if (inMgr != null){ - RSGroupInfo groupInfo = inMgr.getRSGroupOfServer(deadServerName.getAddress()); - rsGroupName = groupInfo == null ? RSGroupInfo.DEFAULT_GROUP : groupInfo.getName(); - } - - - - - - <%if rsGroupName != null %> - - - - <%java> - } - - - - - - -
ServerNameStop timeRSGroup
<% deadServerName %><% deadServerUtil.getTimeOfDeath(deadServerName) %><% rsGroupName %>
Total: servers: <% deadServers.size() %>
- - - -<%def peerConfigs> -<%java> - List peers = null; - if (master.getReplicationPeerManager() != null) { - peers = master.getReplicationPeerManager().listPeers(null); - } - - - - - - - - - - - - - - - - - -<%if (peers != null && peers.size() > 0)%> - <%for ReplicationPeerDescription peer : peers %> - <%java> - String peerId = peer.getPeerId(); - ReplicationPeerConfig peerConfig = peer.getPeerConfig(); - - - - - - - - - - - - - - - - - -
Peer IdCluster KeyEndpointStateIsSerialRemote WALSync Replication StateBandwidthReplicateAllNamespacesExclude NamespacesTable CfsExclude Table Cfs
<% peerId %><% peerConfig.getClusterKey() %><% peerConfig.getReplicationEndpointImpl() %><% peer.isEnabled() ? "ENABLED" : "DISABLED" %><% peerConfig.isSerial() %><% peerConfig.getRemoteWALDir() == null ? "" : peerConfig.getRemoteWALDir() %> - <% peer.getSyncReplicationState() %> - <% peerConfig.getBandwidth() == 0? "UNLIMITED" : Strings.humanReadableInt(peerConfig.getBandwidth()) %><% peerConfig.replicateAllUserTables() %> - <% peerConfig.getNamespaces() == null ? "" : ReplicationPeerConfigUtil.convertToString(peerConfig.getNamespaces()).replaceAll(";", "; ") %> - - <% peerConfig.getExcludeNamespaces() == null ? "" : ReplicationPeerConfigUtil.convertToString(peerConfig.getExcludeNamespaces()).replaceAll(";", "; ") %> - - <% peerConfig.getTableCFsMap() == null ? "" : ReplicationPeerConfigUtil.convertToString(peerConfig.getTableCFsMap()).replaceAll(";", "; ") %> - - <% peerConfig.getExcludeTableCFsMap() == null ? "" : ReplicationPeerConfigUtil.convertToString(peerConfig.getExcludeTableCFsMap()).replaceAll(";", "; ") %> -
Total: <% (peers != null) ? peers.size() : 0 %>
- diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RSGroupListTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RSGroupListTmpl.jamon deleted file mode 100644 index 277c90e53b13..000000000000 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RSGroupListTmpl.jamon +++ /dev/null @@ -1,393 +0,0 @@ -<%doc> -Copyright The Apache Software Foundation - -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. - - -<%args> -HMaster master; -ServerManager serverManager; - - -<%import> - java.util.Collections; - java.util.List; - java.util.Map; - java.util.Set; - java.util.stream.Collectors; - org.apache.hadoop.hbase.master.HMaster; - org.apache.hadoop.hbase.RegionMetrics; - org.apache.hadoop.hbase.ServerMetrics; - org.apache.hadoop.hbase.Size; - org.apache.hadoop.hbase.master.ServerManager; - org.apache.hadoop.hbase.net.Address; - org.apache.hadoop.hbase.rsgroup.RSGroupInfo; - org.apache.hadoop.hbase.rsgroup.RSGroupUtil; - org.apache.hadoop.util.StringUtils; - org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix; - -<%java> -List groups = master.getRSGroupInfoManager().listRSGroups(); - -<%if (groups != null && groups.size() > 0)%> - -<%java> -RSGroupInfo [] rsGroupInfos = groups.toArray(new RSGroupInfo[groups.size()]); -Map collectServers = Collections.emptyMap(); -if (master.getServerManager() != null) { - collectServers = - master.getServerManager().getOnlineServers().entrySet().stream() - .collect(Collectors.toMap(p -> p.getKey().getAddress(), Map.Entry::getValue)); -} - - -
- -
-
- <& rsgroup_baseStats; rsGroupInfos = rsGroupInfos; collectServers= collectServers &> -
-
- <& rsgroup_memoryStats; rsGroupInfos = rsGroupInfos; collectServers= collectServers &> -
-
- <& rsgroup_requestStats; rsGroupInfos = rsGroupInfos; collectServers= collectServers &> -
-
- <& rsgroup_storeStats; rsGroupInfos = rsGroupInfos; collectServers= collectServers &> -
-
- <& rsgroup_compactStats; rsGroupInfos = rsGroupInfos; collectServers= collectServers &> -
-
-
- - - -<%def rsgroup_baseStats> -<%args> - RSGroupInfo [] rsGroupInfos; - Map collectServers; - - - - - - - - - - - -<%java> - int totalOnlineServers = 0; - int totalDeadServers = 0; - int totalTables = 0; - int totalRequests = 0; - int totalRegions = 0; - for (RSGroupInfo rsGroupInfo: rsGroupInfos) { - String rsGroupName = rsGroupInfo.getName(); - int onlineServers = 0; - int deadServers = 0; - int tables = 0; - long requestsPerSecond = 0; - int numRegionsOnline = 0; - Set
servers = rsGroupInfo.getServers(); - for (Address server : servers) { - ServerMetrics sl = collectServers.get(server); - if (sl != null) { - requestsPerSecond += sl.getRequestCountPerSecond(); - numRegionsOnline += sl.getRegionMetrics().size(); - //rsgroup total - totalRegions += sl.getRegionMetrics().size(); - totalRequests += sl.getRequestCountPerSecond(); - totalOnlineServers++; - onlineServers++; - } else { - totalDeadServers++; - deadServers++; - } - } - tables = RSGroupUtil.listTablesInRSGroup(master, rsGroupInfo.getName()).size(); - totalTables += tables; - double avgLoad = onlineServers == 0 ? 0 : - (double)numRegionsOnline / (double)onlineServers; - -
- - - - - - - - -<%java> -} - - - - - - - - - -
RSGroup NameNum. Online ServersNum. Dead ServersNum. TablesRequests Per SecondNum. RegionsAverage Load
<& rsGroupLink; rsGroupName=rsGroupName; &><% onlineServers %><% deadServers %><% tables %><% requestsPerSecond %><% numRegionsOnline %><% StringUtils.limitDecimalTo2(avgLoad) %>
Total:<% rsGroupInfos.length %><% totalOnlineServers %><% totalDeadServers %><% totalTables %><% totalRequests %><% totalRegions %><% StringUtils.limitDecimalTo2(master.getServerManager().getAverageLoad()) %>
- - -<%def rsgroup_memoryStats> -<%args> - RSGroupInfo [] rsGroupInfos; - Map collectServers; - - - - - - - - - -<%java> - final String ZEROMB = "0 MB"; - for (RSGroupInfo rsGroupInfo: rsGroupInfos) { - String usedHeapStr = ZEROMB; - String maxHeapStr = ZEROMB; - String memstoreSizeStr = ZEROMB; - String rsGroupName = rsGroupInfo.getName(); - long usedHeap = 0; - long maxHeap = 0; - long memstoreSize = 0; - for (Address server : rsGroupInfo.getServers()) { - ServerMetrics sl = collectServers.get(server); - if (sl != null) { - usedHeap += (long) sl.getUsedHeapSize().get(Size.Unit.MEGABYTE); - maxHeap += (long) sl.getMaxHeapSize().get(Size.Unit.MEGABYTE); - memstoreSize += (long) sl.getRegionMetrics().values().stream().mapToDouble( - rm -> rm.getMemStoreSize().get(Size.Unit.MEGABYTE)).sum(); - } - } - - if (usedHeap > 0) { - usedHeapStr = TraditionalBinaryPrefix.long2String(usedHeap - * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - if (maxHeap > 0) { - maxHeapStr = TraditionalBinaryPrefix.long2String(maxHeap - * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - if (memstoreSize > 0) { - memstoreSizeStr = TraditionalBinaryPrefix.long2String(memstoreSize - * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - - - - - - - - -<%java> -} - -
RSGroup NameUsed HeapMax HeapMemstore Size
<& rsGroupLink; rsGroupName=rsGroupName; &><% usedHeapStr %><% maxHeapStr %><% memstoreSizeStr %>
- - -<%def rsgroup_requestStats> -<%args> - RSGroupInfo [] rsGroupInfos; - Map collectServers; - - - - - - - - -<%java> - for (RSGroupInfo rsGroupInfo: rsGroupInfos) { - String rsGroupName = rsGroupInfo.getName(); - long requestsPerSecond = 0; - long readRequests = 0; - long writeRequests = 0; - for (Address server : rsGroupInfo.getServers()) { - ServerMetrics sl = collectServers.get(server); - if (sl != null) { - for (RegionMetrics rm : sl.getRegionMetrics().values()) { - readRequests += rm.getReadRequestCount(); - writeRequests += rm.getWriteRequestCount(); - } - requestsPerSecond += sl.getRequestCountPerSecond(); - } - } - - - - - - - -<%java> -} - -
RSGroup NameRequest Per SecondRead Request CountWrite Request Count
<& rsGroupLink; rsGroupName=rsGroupName; &><% requestsPerSecond %><% readRequests %><% writeRequests %>
- - - -<%def rsgroup_storeStats> -<%args> - RSGroupInfo [] rsGroupInfos; - Map collectServers; - - - - - - - - - - - -<%java> - final String ZEROKB = "0 KB"; - final String ZEROMB = "0 MB"; - for (RSGroupInfo rsGroupInfo: rsGroupInfos) { - String uncompressedStorefileSizeStr = ZEROMB; - String storefileSizeStr = ZEROMB; - String indexSizeStr = ZEROKB; - String bloomSizeStr = ZEROKB; - String rsGroupName = rsGroupInfo.getName(); - int numStores = 0; - long numStorefiles = 0; - long uncompressedStorefileSize = 0; - long storefileSize = 0; - long indexSize = 0; - long bloomSize = 0; - int count = 0; - for (Address server : rsGroupInfo.getServers()) { - ServerMetrics sl = collectServers.get(server); - if (sl != null) { - for (RegionMetrics rm : sl.getRegionMetrics().values()) { - numStores += rm.getStoreCount(); - numStorefiles += rm.getStoreFileCount(); - uncompressedStorefileSize += rm.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE); - storefileSize += rm.getStoreFileSize().get(Size.Unit.MEGABYTE); - indexSize += rm.getStoreFileUncompressedDataIndexSize().get(Size.Unit.KILOBYTE); - bloomSize += rm.getBloomFilterSize().get(Size.Unit.KILOBYTE); - } - count++; - } - } - if (uncompressedStorefileSize > 0) { - uncompressedStorefileSizeStr = TraditionalBinaryPrefix. - long2String(uncompressedStorefileSize * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - if (storefileSize > 0) { - storefileSizeStr = TraditionalBinaryPrefix. - long2String(storefileSize * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - if (indexSize > 0) { - indexSizeStr = TraditionalBinaryPrefix. - long2String(indexSize * TraditionalBinaryPrefix.KILO.value, "B", 1); - } - if (bloomSize > 0) { - bloomSizeStr = TraditionalBinaryPrefix. - long2String(bloomSize * TraditionalBinaryPrefix.KILO.value, "B", 1); - } - - - - - - - - - - -<%java> -} - -
RSGroup NameNum. StoresNum. StorefilesStorefile Size UncompressedStorefile SizeIndex SizeBloom Size
<& rsGroupLink; rsGroupName=rsGroupName; &><% numStores %><% numStorefiles %><% uncompressedStorefileSizeStr %><% storefileSizeStr %><% indexSizeStr %><% bloomSizeStr %>
- - -<%def rsgroup_compactStats> -<%args> - RSGroupInfo [] rsGroupInfos; - Map collectServers; - - - - - - - - - -<%java> - for (RSGroupInfo rsGroupInfo: rsGroupInfos) { - String rsGroupName = rsGroupInfo.getName(); - int numStores = 0; - long totalCompactingCells = 0; - long totalCompactedCells = 0; - long remainingCells = 0; - long compactionProgress = 0; - for (Address server : rsGroupInfo.getServers()) { - ServerMetrics sl = collectServers.get(server); - if (sl != null) { - for (RegionMetrics rl : sl.getRegionMetrics().values()) { - totalCompactingCells += rl.getCompactingCellCount(); - totalCompactedCells += rl.getCompactedCellCount(); - } - } - } - remainingCells = totalCompactingCells - totalCompactedCells; - String percentDone = ""; - if (totalCompactingCells > 0) { - percentDone = String.format("%.2f", 100 * - ((float) totalCompactedCells / totalCompactingCells)) + "%"; - } - - - - - - - - -<%java> -} - -
RSGroup NameNum. Compacting CellsNum. Compacted CellsRemaining CellsCompaction Progress
<& rsGroupLink; rsGroupName=rsGroupName; &><% totalCompactingCells %><% totalCompactedCells %><% remainingCells %><% percentDone %>
- - - -<%def rsGroupLink> - <%args> - String rsGroupName; - - ><% rsGroupName %> - diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionServerListTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionServerListTmpl.jamon deleted file mode 100644 index c748f4162179..000000000000 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionServerListTmpl.jamon +++ /dev/null @@ -1,538 +0,0 @@ -<%doc> -Copyright The Apache Software Foundation - -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. - - -<%args> -List servers = null; -HMaster master; - - -<%import> - java.util.*; - org.apache.hadoop.hbase.master.HMaster; - org.apache.hadoop.hbase.procedure2.util.StringUtils; - org.apache.hadoop.hbase.replication.ReplicationLoadSource; - org.apache.hadoop.hbase.RegionMetrics; - org.apache.hadoop.hbase.ServerMetrics; - org.apache.hadoop.hbase.ServerName; - org.apache.hadoop.hbase.Size; - org.apache.hadoop.hbase.util.VersionInfo; - org.apache.hadoop.hbase.util.Pair; - org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix; - org.apache.hadoop.hbase.net.Address; - org.apache.hadoop.hbase.rsgroup.RSGroupInfo; - org.apache.hadoop.hbase.rsgroup.RSGroupUtil; - - -<%if (servers != null && servers.size() > 0)%> - -<%java> -ServerName [] serverNames = servers.toArray(new ServerName[servers.size()]); -Arrays.sort(serverNames); - - -
- -
-
- <& baseStats; serverNames = serverNames; &> -
-
- <& memoryStats; serverNames = serverNames; &> -
-
- <& requestStats; serverNames = serverNames; &> -
-
- <& storeStats; serverNames = serverNames; &> -
-
- <& compactionStats; serverNames = serverNames; &> -
-
- <& replicationStats; serverNames = serverNames; &> -
-
-
- - - -<%def baseStats> -<%args> - ServerName [] serverNames; - - - - - - - - - - - - <%if !master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null %> - <%if RSGroupUtil.isRSGroupEnabled(master.getConfiguration()) %> - - - - - - -<%java> - int totalRegions = 0; - int totalRequestsPerSecond = 0; - int inconsistentNodeNum = 0; - String state = "Normal"; - String masterVersion = VersionInfo.getVersion(); - Set decommissionedServers = new HashSet<>(master.listDecommissionedRegionServers()); - String rsGroupName = "default"; - List groups; - Map server2GroupMap = new HashMap<>(); - if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null - && RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { - groups = master.getRSGroupInfoManager().listRSGroups(); - groups.forEach(group -> { - group.getServers().forEach(address -> server2GroupMap.put(address, group)); - }); - } - for (ServerName serverName: serverNames) { - if (decommissionedServers.contains(serverName)) { - state = "Decommissioned"; - } - ServerMetrics sl = master.getServerManager().getLoad(serverName); - String version = master.getRegionServerVersion(serverName); - if (!masterVersion.equals(version)) { - inconsistentNodeNum ++; - } - - double requestsPerSecond = 0.0; - int numRegionsOnline = 0; - long lastContact = 0; - - if (sl != null) { - requestsPerSecond = sl.getRequestCountPerSecond(); - numRegionsOnline = sl.getRegionMetrics().size(); - totalRegions += sl.getRegionMetrics().size(); - totalRequestsPerSecond += sl.getRequestCountPerSecond(); - lastContact = (System.currentTimeMillis() - sl.getReportTimestamp())/1000; - } - long startcode = serverName.getStartcode(); - if (!master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null - && RSGroupUtil.isRSGroupEnabled(master.getConfiguration())) { - rsGroupName = server2GroupMap.get(serverName.getAddress()).getName(); - } - - - - - - - - - - <%if !master.isInMaintenanceMode() && master.getMasterCoprocessorHost() != null %> - <%if RSGroupUtil.isRSGroupEnabled(master.getConfiguration()) %> - - - - -<%java> -} - - - - - - -<%if inconsistentNodeNum > 0%> - -<%else> - - - - - -
ServerNameStateStart timeLast contactVersionRequests Per SecondNum. RegionsRSGroup
<& serverNameLink; serverName=serverName; &><% state %><% new Date(startcode) %><% TraditionalBinaryPrefix.long2String(lastContact, "s", 1) %><% version %><% String.format("%,.0f", requestsPerSecond) %><% String.format("%,d", numRegionsOnline) %><% rsGroupName %>
Total:<% servers.size() %><% inconsistentNodeNum %> nodes with inconsistent version<% totalRequestsPerSecond %><% totalRegions %>
- - -<%def memoryStats> -<%args> - ServerName [] serverNames; - - - - - - - - - - - - -<%java> -final String ZEROMB = "0 MB"; -for (ServerName serverName: serverNames) { - String usedHeapStr = ZEROMB; - String maxHeapStr = ZEROMB; - String memStoreSizeMBStr = ZEROMB; - ServerMetrics sl = master.getServerManager().getLoad(serverName); - if (sl != null) { - long memStoreSizeMB = 0; - for (RegionMetrics rl : sl.getRegionMetrics().values()) { - memStoreSizeMB += rl.getMemStoreSize().get(Size.Unit.MEGABYTE); - } - if (memStoreSizeMB > 0) { - memStoreSizeMBStr = TraditionalBinaryPrefix.long2String(memStoreSizeMB - * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - - double usedHeapSizeMB = sl.getUsedHeapSize().get(Size.Unit.MEGABYTE); - if (usedHeapSizeMB > 0) { - usedHeapStr = TraditionalBinaryPrefix.long2String((long) usedHeapSizeMB - * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - double maxHeapSizeMB = sl.getMaxHeapSize().get(Size.Unit.MEGABYTE); - if (maxHeapSizeMB > 0) { - maxHeapStr = TraditionalBinaryPrefix.long2String((long) maxHeapSizeMB - * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - - - - - - - -<%java> - } else { - -<& emptyStat; serverName=serverName; &> -<%java> - } -} - - -
ServerNameUsed HeapMax HeapMemstore Size
<& serverNameLink; serverName=serverName; &><% usedHeapStr %><% maxHeapStr %><% memStoreSizeMBStr %>
- - - -<%def requestStats> -<%args> - ServerName [] serverNames; - - - - - - - - - - - - -<%java> -for (ServerName serverName: serverNames) { - -ServerMetrics sl = master.getServerManager().getLoad(serverName); -if (sl != null) { - long readRequestCount = 0; - long writeRequestCount = 0; - long filteredReadRequestCount = 0; - for (RegionMetrics rl : sl.getRegionMetrics().values()) { - readRequestCount += rl.getReadRequestCount(); - writeRequestCount += rl.getWriteRequestCount(); - filteredReadRequestCount += rl.getFilteredReadRequestCount(); - } - - - - - - - - -<%java> - } else { - -<& emptyStat; serverName=serverName; &> -<%java> - } -} - - -
ServerNameRequest Per SecondRead Request CountFiltered Read Request CountWrite Request Count
<& serverNameLink; serverName=serverName; &><% String.format("%,d", sl.getRequestCountPerSecond()) %><% String.format("%,d", readRequestCount) %><% String.format("%,d", filteredReadRequestCount) %><% String.format("%,d", writeRequestCount) %>
- - - -<%def storeStats> -<%args> - ServerName [] serverNames; - - - - - - - - - - - - - - -<%java> -final String ZEROKB = "0 KB"; -final String ZEROMB = "0 MB"; -for (ServerName serverName: serverNames) { - - String storeUncompressedSizeMBStr = ZEROMB; - String storeFileSizeMBStr = ZEROMB; - String totalStaticIndexSizeKBStr = ZEROKB; - String totalStaticBloomSizeKBStr = ZEROKB; - ServerMetrics sl = master.getServerManager().getLoad(serverName); - if (sl != null) { - long storeCount = 0; - long storeFileCount = 0; - long storeUncompressedSizeMB = 0; - long storeFileSizeMB = 0; - long totalStaticIndexSizeKB = 0; - long totalStaticBloomSizeKB = 0; - for (RegionMetrics rl : sl.getRegionMetrics().values()) { - storeCount += rl.getStoreCount(); - storeFileCount += rl.getStoreFileCount(); - storeUncompressedSizeMB += rl.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE); - storeFileSizeMB += rl.getStoreFileSize().get(Size.Unit.MEGABYTE); - totalStaticIndexSizeKB += rl.getStoreFileUncompressedDataIndexSize().get(Size.Unit.KILOBYTE); - totalStaticBloomSizeKB += rl.getBloomFilterSize().get(Size.Unit.KILOBYTE); - } - if (storeUncompressedSizeMB > 0) { - storeUncompressedSizeMBStr = TraditionalBinaryPrefix. - long2String(storeUncompressedSizeMB * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - if (storeFileSizeMB > 0) { - storeFileSizeMBStr = TraditionalBinaryPrefix. - long2String(storeFileSizeMB * TraditionalBinaryPrefix.MEGA.value, "B", 1); - } - if (totalStaticIndexSizeKB > 0) { - totalStaticIndexSizeKBStr = TraditionalBinaryPrefix. - long2String(totalStaticIndexSizeKB * TraditionalBinaryPrefix.KILO.value, "B", 1); - } - if (totalStaticBloomSizeKB > 0) { - totalStaticBloomSizeKBStr = TraditionalBinaryPrefix. - long2String(totalStaticBloomSizeKB * TraditionalBinaryPrefix.KILO.value, "B", 1); - } - - - - - - - - - - -<%java> - } else { - -<& emptyStat; serverName=serverName; &> -<%java> - } -} - - -
ServerNameNum. StoresNum. StorefilesStorefile Size UncompressedStorefile SizeIndex SizeBloom Size
<& serverNameLink; serverName=serverName; &><% String.format("%,d", storeCount) %><% String.format("%,d", storeFileCount) %><% storeUncompressedSizeMBStr %><% storeFileSizeMBStr %><% totalStaticIndexSizeKBStr %><% totalStaticBloomSizeKBStr %>
- - -<%def compactionStats> -<%args> - ServerName [] serverNames; - - - - - - - - - - - - -<%java> -for (ServerName serverName: serverNames) { - -ServerMetrics sl = master.getServerManager().getLoad(serverName); -if (sl != null) { -long totalCompactingCells = 0; -long totalCompactedCells = 0; -for (RegionMetrics rl : sl.getRegionMetrics().values()) { - totalCompactingCells += rl.getCompactingCellCount(); - totalCompactedCells += rl.getCompactedCellCount(); -} -String percentDone = ""; -if (totalCompactingCells > 0) { - percentDone = String.format("%.2f", 100 * - ((float) totalCompactedCells / totalCompactingCells)) + "%"; -} - - - - - - - - -<%java> - } else { - -<& emptyStat; serverName=serverName; &> -<%java> - } -} - - -
ServerNameNum. Compacting CellsNum. Compacted CellsRemaining CellsCompaction Progress
<& serverNameLink; serverName=serverName; &><% String.format("%,d", totalCompactingCells) %><% String.format("%,d", totalCompactedCells) %><% String.format("%,d", totalCompactingCells - totalCompactedCells) %><% percentDone %>
- - -<%def replicationStats> -<%args> - ServerName [] serverNames; - -<%java> - HashMap>> replicationLoadSourceMap - = master.getReplicationLoad(serverNames); - List peers = null; - if (replicationLoadSourceMap != null && replicationLoadSourceMap.size() > 0){ - peers = new ArrayList<>(replicationLoadSourceMap.keySet()); - Collections.sort(peers); - } - - -<%if (replicationLoadSourceMap != null && replicationLoadSourceMap.size() > 0) %> - -
- -
- <%java> - active = "active"; - for (String peer : peers){ - -
- - - - - - - - - <%for Pair pair: replicationLoadSourceMap.get(peer) %> - - - - - - - -
ServerAgeOfLastShippedOpSizeOfLogQueueReplicationLag
<& serverNameLink; serverName=pair.getFirst(); &><% StringUtils.humanTimeDiff(pair.getSecond().getAgeOfLastShippedOp()) %><% pair.getSecond().getSizeOfLogQueue() %><% pair.getSecond().getReplicationLag() == Long.MAX_VALUE ? "UNKNOWN" : StringUtils.humanTimeDiff(pair.getSecond().getReplicationLag()) %>
-
- <%java> - active = ""; - } - -
-

If the replication delay is UNKNOWN, that means this walGroup doesn't start replicate yet and it may get disabled.

-
-<%else> -

No Peers Metrics

- - - - - -<%def serverNameLink> - <%args> - ServerName serverName; - - <%java> - int infoPort = master.getRegionServerInfoPort(serverName); - String url = "//" + serverName.getHostname() + ":" + infoPort + "/rs-status"; - - - <%if infoPort > 0%> - <% serverName.getServerName() %> - <%else> - <% serverName.getServerName() %> - - - -<%def emptyStat> - <%args> - ServerName serverName; - - - <& serverNameLink; serverName=serverName; &> - - - - - - - - - - - - - - - diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionVisualizerTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionVisualizerTmpl.jamon index 9a98cfefed7f..e69de29bb2d1 100644 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionVisualizerTmpl.jamon +++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionVisualizerTmpl.jamon @@ -1,119 +0,0 @@ -<%doc> - -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. - - - - - - -
- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index 6f235b2156f3..bd5ad2275aa6 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -144,7 +144,6 @@ import org.apache.hadoop.hbase.master.hbck.HbckChore; import org.apache.hadoop.hbase.master.http.MasterDumpServlet; import org.apache.hadoop.hbase.master.http.MasterRedirectServlet; -import org.apache.hadoop.hbase.master.http.MasterStatusServlet; import org.apache.hadoop.hbase.master.http.api_v1.ResourceConfigFactory; import org.apache.hadoop.hbase.master.http.hbck.HbckConfigFactory; import org.apache.hadoop.hbase.master.janitor.CatalogJanitor; @@ -772,7 +771,6 @@ protected MasterRpcServices createRpcServices() throws IOException { @Override protected void configureInfoServer(InfoServer infoServer) { - infoServer.addUnprivilegedServlet("master-status", "/master-status", MasterStatusServlet.class); infoServer.addUnprivilegedServlet("api_v1", "/api/v1/*", buildApiV1Servlet()); infoServer.addUnprivilegedServlet("hbck", "/hbck/*", buildHbckServlet()); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/http/MasterStatusServlet.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/http/MasterStatusServlet.java deleted file mode 100644 index 09bb5375a5d5..000000000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/http/MasterStatusServlet.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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. - */ -package org.apache.hadoop.hbase.master.http; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.ServerName; -import org.apache.hadoop.hbase.client.RegionInfoBuilder; -import org.apache.hadoop.hbase.master.HMaster; -import org.apache.hadoop.hbase.master.RegionState; -import org.apache.hadoop.hbase.master.ServerManager; -import org.apache.hadoop.hbase.master.assignment.RegionStateNode; -import org.apache.hadoop.hbase.tmpl.master.MasterStatusTmpl; -import org.apache.hadoop.hbase.util.FSUtils; -import org.apache.yetus.audience.InterfaceAudience; - -/** - * The servlet responsible for rendering the index page of the master. - */ -@InterfaceAudience.Private -public class MasterStatusServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); - assert master != null : "No Master in context!"; - - response.setContentType("text/html"); - - Configuration conf = master.getConfiguration(); - - Map frags = getFragmentationInfo(master, conf); - ServerName metaLocation = null; - List servers = null; - Set deadServers = null; - - if (master.isActiveMaster()) { - metaLocation = getMetaLocationOrNull(master); - ServerManager serverManager = master.getServerManager(); - if (serverManager != null) { - deadServers = serverManager.getDeadServers().copyServerNames(); - servers = serverManager.getOnlineServersList(); - } - } - - MasterStatusTmpl tmpl = - new MasterStatusTmpl().setFrags(frags).setMetaLocation(metaLocation).setServers(servers) - .setDeadServers(deadServers).setCatalogJanitorEnabled(master.isCatalogJanitorEnabled()); - - if (request.getParameter("filter") != null) tmpl.setFilter(request.getParameter("filter")); - if (request.getParameter("format") != null) tmpl.setFormat(request.getParameter("format")); - tmpl.render(response.getWriter(), master); - } - - private ServerName getMetaLocationOrNull(HMaster master) { - RegionStateNode rsn = master.getAssignmentManager().getRegionStates() - .getRegionStateNode(RegionInfoBuilder.FIRST_META_REGIONINFO); - if (rsn != null) { - return rsn.isInState(RegionState.State.OPEN) ? rsn.getRegionLocation() : null; - } - return null; - } - - private Map getFragmentationInfo(HMaster master, Configuration conf) - throws IOException { - boolean showFragmentation = conf.getBoolean("hbase.master.ui.fragmentation.enabled", false); - if (showFragmentation) { - return FSUtils.getTableFragmentation(master); - } else { - return null; - } - } -} diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/http/RegionVisualizer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/http/RegionVisualizer.java index 09171c3a8c2f..ceb08bcedf2d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/http/RegionVisualizer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/http/RegionVisualizer.java @@ -58,7 +58,7 @@ /** * Support class for the "Region Visualizer" rendered out of - * {@code src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionVisualizerTmpl.jamon} + * {@code src/main/resources/hbase-webapps/master/regionVisualizer.jsp} */ @InterfaceAudience.Private public class RegionVisualizer extends AbstractHBaseTool { diff --git a/hbase-server/src/main/resources/hbase-webapps/master/tablesDetailed.jsp b/hbase-server/src/main/resources/hbase-webapps/master/tablesDetailed.jsp index b2f3938f56ff..7e2a63e983e2 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/tablesDetailed.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/tablesDetailed.jsp @@ -21,10 +21,31 @@ import="static org.apache.commons.lang3.StringEscapeUtils.escapeXml" import="java.util.ArrayList" import="java.util.List" + import="org.apache.hadoop.hbase.client.TableDescriptor" + import="org.apache.hadoop.hbase.master.HMaster" + import="java.util.Map" + import="java.io.IOException" %> + +<%! + // TODO: Extract this to common class! + public static String getUserTables(HMaster master, List tables){ + if (master.isInitialized()){ + try { + Map descriptorMap = master.getTableDescriptors().getAll(); + if (descriptorMap != null) { + for (TableDescriptor desc : descriptorMap.values()) { + if (!desc.getTableName().isSystemTable()) { + tables.add(desc); + } + } + } + } catch (IOException e) { + return "Got user tables error, " + e.getMessage(); + } + } + return null; + } %> -<%@ page import="org.apache.hadoop.hbase.client.TableDescriptor" %> -<%@ page import="org.apache.hadoop.hbase.master.HMaster" %> -<%@ page import="org.apache.hadoop.hbase.tmpl.master.MasterStatusTmplImpl" %> <% HMaster master = (HMaster) getServletContext().getAttribute(HMaster.MASTER); pageContext.setAttribute("pageTitle", "HBase Master: " + master.getServerName()); @@ -41,7 +62,7 @@ <% List tables = new ArrayList(); - String errorMessage = MasterStatusTmplImpl.getUserTables(master, tables); + String errorMessage = getUserTables(master, tables); if (tables.size() == 0 && errorMessage != null) { %>

<%= errorMessage %>

<% } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/http/TestMasterStatusServlet.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/http/TestMasterStatusServlet.java deleted file mode 100644 index d7209662dc5c..000000000000 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/http/TestMasterStatusServlet.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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. - */ -package org.apache.hadoop.hbase.master.http; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.HBaseClassTestRule; -import org.apache.hadoop.hbase.HBaseConfiguration; -import org.apache.hadoop.hbase.ServerName; -import org.apache.hadoop.hbase.TableName; -import org.apache.hadoop.hbase.client.Admin; -import org.apache.hadoop.hbase.client.RegionInfo; -import org.apache.hadoop.hbase.client.RegionInfoBuilder; -import org.apache.hadoop.hbase.client.TableDescriptor; -import org.apache.hadoop.hbase.client.TableDescriptorBuilder; -import org.apache.hadoop.hbase.master.DeadServer; -import org.apache.hadoop.hbase.master.HMaster; -import org.apache.hadoop.hbase.master.RegionState; -import org.apache.hadoop.hbase.master.ServerManager; -import org.apache.hadoop.hbase.master.assignment.AssignmentManager; -import org.apache.hadoop.hbase.master.assignment.RegionStates; -import org.apache.hadoop.hbase.testclassification.MasterTests; -import org.apache.hadoop.hbase.testclassification.MediumTests; -import org.apache.hadoop.hbase.tmpl.master.MasterStatusTmpl; -import org.apache.hadoop.hbase.util.Bytes; -import org.apache.hadoop.hbase.zookeeper.ZKWatcher; -import org.apache.hadoop.hbase.zookeeper.ZNodePaths; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.mockito.Mockito; - -import org.apache.hbase.thirdparty.com.google.common.collect.Lists; - -/** - * Tests for the master status page and its template. - */ -@Category({ MasterTests.class, MediumTests.class }) -public class TestMasterStatusServlet { - - @ClassRule - public static final HBaseClassTestRule CLASS_RULE = - HBaseClassTestRule.forClass(TestMasterStatusServlet.class); - - private HMaster master; - private Configuration conf; - private Admin admin; - - static final ServerName FAKE_HOST = ServerName.valueOf("fakehost", 12345, 1234567890); - static final TableDescriptor FAKE_TABLE = - TableDescriptorBuilder.newBuilder(TableName.valueOf("mytable")).build(); - - static final RegionInfo FAKE_HRI = RegionInfoBuilder.newBuilder(FAKE_TABLE.getTableName()) - .setStartKey(Bytes.toBytes("a")).setEndKey(Bytes.toBytes("b")).build(); - - @Before - public void setupBasicMocks() { - conf = HBaseConfiguration.create(); - - master = Mockito.mock(HMaster.class); - Mockito.doReturn(FAKE_HOST).when(master).getServerName(); - Mockito.doReturn(conf).when(master).getConfiguration(); - - // Fake DeadServer - DeadServer deadServer = Mockito.mock(DeadServer.class); - // Fake serverManager - ServerManager serverManager = Mockito.mock(ServerManager.class); - Mockito.doReturn(1.0).when(serverManager).getAverageLoad(); - Mockito.doReturn(serverManager).when(master).getServerManager(); - Mockito.doReturn(deadServer).when(serverManager).getDeadServers(); - - // Fake AssignmentManager and RIT - AssignmentManager am = Mockito.mock(AssignmentManager.class); - RegionStates rs = Mockito.mock(RegionStates.class); - List regionsInTransition = new ArrayList<>(); - regionsInTransition - .add(new RegionState(FAKE_HRI, RegionState.State.CLOSING, 12345L, FAKE_HOST)); - Mockito.doReturn(rs).when(am).getRegionStates(); - Mockito.doReturn(regionsInTransition).when(rs).getRegionsInTransition(); - Mockito.doReturn(am).when(master).getAssignmentManager(); - Mockito.doReturn(serverManager).when(master).getServerManager(); - - // Fake ZKW - ZKWatcher zkw = Mockito.mock(ZKWatcher.class); - Mockito.doReturn(new ZNodePaths(conf)).when(zkw).getZNodePaths(); - Mockito.doReturn("fakequorum").when(zkw).getQuorum(); - Mockito.doReturn(zkw).when(master).getZooKeeper(); - - // Fake ActiveMaster - Mockito.doReturn(Optional.of(FAKE_HOST)).when(master).getActiveMaster(); - - // Mock admin - admin = Mockito.mock(Admin.class); - } - - private void setupMockTables() throws IOException { - List tables = - Arrays.asList(TableDescriptorBuilder.newBuilder(TableName.valueOf("foo")).build(), - TableDescriptorBuilder.newBuilder(TableName.valueOf("bar")).build()); - Mockito.doReturn(tables).when(admin).listTableDescriptors(); - } - - @Test - public void testStatusTemplateNoTables() throws IOException { - new MasterStatusTmpl().render(new StringWriter(), master); - } - - @Test - public void testStatusTemplateMetaAvailable() throws IOException { - setupMockTables(); - - new MasterStatusTmpl().setMetaLocation(ServerName.valueOf("metaserver,123,12345")) - .render(new StringWriter(), master); - } - - @Test - public void testStatusTemplateWithServers() throws IOException { - setupMockTables(); - - List servers = Lists.newArrayList(ServerName.valueOf("rootserver,123,12345"), - ServerName.valueOf("metaserver,123,12345")); - Set deadServers = - new HashSet<>(Lists.newArrayList(ServerName.valueOf("badserver,123,12345"), - ServerName.valueOf("uglyserver,123,12345"))); - - new MasterStatusTmpl().setMetaLocation(ServerName.valueOf("metaserver,123,12345")) - .setServers(servers).setDeadServers(deadServers).render(new StringWriter(), master); - } -} From 40987bf509b5ef8fe9eea314974fe4c3baf821d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Paksy?= Date: Mon, 31 Mar 2025 18:04:10 +0200 Subject: [PATCH 12/31] HBASE-29223 Adjust links to master status page --- .../apache/hadoop/hbase/tmpl/regionserver/RSStatusTmpl.jamon | 2 +- .../resources/hbase-webapps/master/backupMasterStatus.jsp | 4 ++-- .../src/main/resources/hbase-webapps/master/header.jsp | 4 ++-- .../test/java/org/apache/hadoop/hbase/TestInfoServers.java | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RSStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RSStatusTmpl.jamon index 4b8047b9e446..15426675deca 100644 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RSStatusTmpl.jamon +++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RSStatusTmpl.jamon @@ -243,7 +243,7 @@ org.apache.hadoop.hbase.zookeeper.MasterAddressTracker; <%else> <%java> String host = masterServerName.getHostname() + ":" + infoPort; - String url = "//" + host + "/master-status"; + String url = "//" + host + "/master.jsp"; <% host %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/backupMasterStatus.jsp b/hbase-server/src/main/resources/hbase-webapps/master/backupMasterStatus.jsp index ee183b51a785..cada34472c95 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/backupMasterStatus.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/backupMasterStatus.jsp @@ -35,7 +35,7 @@

Backup Master <%= master.getServerName().getHostname() %>

-

Current Active Master: Current Active Master: <%= active_master.getHostname() %>

<% } else { %>

Backup Masters

@@ -54,7 +54,7 @@ int infoPort = master.getBackupMasterInfoPort(serverName); %> - <%= serverName.getHostname() %> <%= serverName.getPort() %> diff --git a/hbase-server/src/main/resources/hbase-webapps/master/header.jsp b/hbase-server/src/main/resources/hbase-webapps/master/header.jsp index f2656612cf86..dba1b611fc24 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/header.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/header.jsp @@ -43,13 +43,13 @@