This is an automated email from the ASF dual-hosted git repository.
nihaljain pushed a commit to branch branch-2.5
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2.5 by this push:
new 526bad77652 HBASE-29028 Backport missing UI patches to branch-2.5
(#6542)
526bad77652 is described below
commit 526bad77652dda83c3e8d48b240323b80f9ac9b1
Author: Dávid Paksy <[email protected]>
AuthorDate: Wed Jan 8 12:57:39 2025 +0100
HBASE-29028 Backport missing UI patches to branch-2.5 (#6542)
* HBASE-27406 Make /prometheus endpoint accessible from HBase UI (#4833)
Signed-off-by: Andor Molnar <[email protected]>
Signed-off-by: Balazs Meszaros <[email protected]>
(cherry picked from commit dffc8e0fbefda603e3c0557bc2ceac600152675e)
* HBASE-27814 Add support for dump and process metrics servlet in REST
InfoServer (#5215)
Other changes:
- Ensure info server stops during stop()
- Extract header and footer. This would fix the log level page layout for
rest web UI (See HBASE-20693)
- Add hostname in the landing page instead of just port similar to other
web UIs
Signed-off-by: Nick Dimiduk <[email protected]>
(cherry picked from commit a683fcfbe8c5c84e58fa8670f4414f9d01ff43ed)
* HBASE-18382 add transport type info into Thrift UI (#880)
Signed-off-by: Wellington Chevreuil <[email protected]>
Signed-off-by: Bharath Vissapragada <[email protected]>
Signed-off-by: Viraj Jasani <[email protected]>
(cherry picked from commit 82e155eb26cddd642e151d9276e2f4f281b4df88)
* HBASE-20693 Refactor thrift jsp's and extract header and footer (#5732)
- Fixes the way logLevel page renders in UI
Signed-off-by: Nick Dimiduk <[email protected]>
(cherry picked from commit ede4ccd2dc5f5690a518f97b6d28a7e18df9584a)
* HBASE-24624 Optimize table.jsp code (#1963)
Signed-off-by: Guangxu Cheng <[email protected]>
(cherry picked from commit 9ad16aa3763d05e85807a5c81b42c03eb2dec4f5)
* HBASE-25402 Sorting order by start key or end key is not considering
empty start key/end key (#2955)
Signed-off-by: Duo Zhang <[email protected]>
Signed-off-by: Pankaj Kumar<[email protected]>
(cherry picked from commit 157200ef8375a91905efb3589393f2ef2b58b970)
* HBASE-27309 Add major compact table or region operation on master web
table page (#4793)
Co-authored-by: zhengsicheng <[email protected]>
Signed-off-by: Duo Zhang <[email protected]>
(cherry picked from commit eb6b2745c550905e92dcfee34e558a0901944da5)
* HBASE-28778 NPE may occur when opening master-status or table.jsp or
procedure.jsp while Master is initializing (#6152)
Signed-off-by: Duo Zhang <[email protected]>
(cherry picked from commit 3caaf2d739106b56ab94a0561e730ff35802610d)
* HBASE-28305 Add "Uncompressed StoreFileSize" column to the table.jsp
(#5620)
Co-authored-by: Haosen Chen <[email protected]>
Signed-off-by: Duo Zhang <[email protected]>
(cherry picked from commit e3a0174e20542e661f787a874870b629a274daf5)
* HBASE-20452 Master UI: Table merge button should validate required fields
before submit
Signed-off-by: tedyu <[email protected]>
(cherry picked from commit 6ce1136ebae75abc2a1d8d35e1963546b8e2d014)
* HBASE-29028 Removed Prometheus links from navbar as the feature
(HBASE-20904) is not even supported by backend.
---------
Co-authored-by: Luca Kovács <[email protected]>
Co-authored-by: Nihal Jain <[email protected]>
Co-authored-by: Beata Sudi <[email protected]>
Co-authored-by: xincunSong <[email protected]>
Co-authored-by: Akshay Sudheer
<[email protected]>
Co-authored-by: SiCheng-Zheng <[email protected]>
Co-authored-by: Peng Lu <[email protected]>
Co-authored-by: haosen chen <[email protected]>
Co-authored-by: Nihal Jain <[email protected]>
Signed-off-by: Andrew Purtell <[email protected]>
Signed-off-by: Nihal Jain <[email protected]>
---
.../apache/hadoop/hbase/rest/RESTDumpServlet.java | 80 +
.../org/apache/hadoop/hbase/rest/RESTServer.java | 39 +-
.../main/resources/hbase-webapps/rest/footer.jsp | 32 +
.../main/resources/hbase-webapps/rest/header.jsp | 72 +
.../resources/hbase-webapps/rest/processRest.jsp | 184 ++
.../src/main/resources/hbase-webapps/rest/rest.jsp | 70 +-
.../hbase/tmpl/master/MasterStatusTmpl.jamon | 10 +-
.../hbase/tmpl/regionserver/RSStatusTmpl.jamon | 17 +-
.../main/resources/hbase-webapps/master/header.jsp | 10 +-
.../main/resources/hbase-webapps/master/table.jsp | 1905 ++++++++++----------
.../hbase-webapps/regionserver/header.jsp | 10 +-
.../main/resources/hbase-webapps/thrift/footer.jsp | 30 +
.../main/resources/hbase-webapps/thrift/header.jsp | 72 +
.../main/resources/hbase-webapps/thrift/thrift.jsp | 91 +-
14 files changed, 1548 insertions(+), 1074 deletions(-)
diff --git
a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTDumpServlet.java
b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTDumpServlet.java
new file mode 100644
index 00000000000..8bb306f7829
--- /dev/null
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTDumpServlet.java
@@ -0,0 +1,80 @@
+/*
+ * 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.rest;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Date;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.http.HttpServer;
+import org.apache.hadoop.hbase.monitoring.StateDumpServlet;
+import org.apache.hadoop.hbase.util.LogMonitoring;
+import org.apache.hadoop.hbase.util.Threads;
+import org.apache.yetus.audience.InterfaceAudience;
+
[email protected]
+public class RESTDumpServlet extends StateDumpServlet {
+ private static final long serialVersionUID = 1L;
+ private static final String LINE =
"===========================================================";
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
+ if (!HttpServer.isInstrumentationAccessAllowed(getServletContext(),
request, response)) {
+ return;
+ }
+
+ RESTServer restServer = (RESTServer)
getServletContext().getAttribute(RESTServer.REST_SERVER);
+ assert restServer != null : "No REST Server in context!";
+
+ response.setContentType("text/plain");
+ OutputStream os = response.getOutputStream();
+ try (PrintWriter out = new PrintWriter(os)) {
+
+ out.println("REST Server status for " + restServer.getServerName() + "
as of " + new Date());
+
+ out.println("\n\nVersion Info:");
+ out.println(LINE);
+ dumpVersionInfo(out);
+
+ out.println("\n\nStacks:");
+ out.println(LINE);
+ out.flush();
+ PrintStream ps = new PrintStream(response.getOutputStream(), false,
"UTF-8");
+ Threads.printThreadInfo(ps, "");
+ ps.flush();
+
+ out.println("\n\nREST Server configuration:");
+ out.println(LINE);
+ Configuration conf = restServer.conf;
+ out.flush();
+ conf.writeXml(os);
+ os.flush();
+
+ out.println("\n\nLogs");
+ out.println(LINE);
+ long tailKb = getTailKbParam(request);
+ LogMonitoring.dumpTailOfLogs(out, tailKb);
+
+ out.flush();
+ }
+ }
+}
diff --git
a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
index 5796cd066f9..dea6f290987 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
@@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.rest;
import static org.apache.hadoop.hbase.http.HttpServerUtil.PATH_SPEC_ANY;
import java.lang.management.ManagementFactory;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
@@ -31,6 +32,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
+import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.http.HttpServerUtil;
import org.apache.hadoop.hbase.http.InfoServer;
import org.apache.hadoop.hbase.log.HBaseMarkers;
@@ -83,6 +85,7 @@ import
org.apache.hbase.thirdparty.org.glassfish.jersey.servlet.ServletContainer
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS)
public class RESTServer implements Constants {
static Logger LOG = LoggerFactory.getLogger("RESTServer");
+ public static final String REST_SERVER = "rest";
static final String REST_CSRF_ENABLED_KEY = "hbase.rest.csrf.enabled";
static final boolean REST_CSRF_ENABLED_DEFAULT = false;
@@ -110,6 +113,7 @@ public class RESTServer implements Constants {
private final UserProvider userProvider;
private Server server;
private InfoServer infoServer;
+ private ServerName serverName;
public RESTServer(Configuration conf) {
RESTServer.conf = conf;
@@ -143,8 +147,7 @@ public class RESTServer implements Constants {
loginServerPrincipal(UserProvider userProvider, Configuration conf) throws
Exception {
Class<? extends ServletContainer> containerClass = ServletContainer.class;
if (userProvider.isHadoopSecurityEnabled() &&
userProvider.isHBaseSecurityEnabled()) {
- String machineName =
Strings.domainNamePointerToHostName(DNS.getDefaultHost(
- conf.get(REST_DNS_INTERFACE, "default"), conf.get(REST_DNS_NAMESERVER,
"default")));
+ String machineName = getHostName(conf);
String keytabFilename = conf.get(REST_KEYTAB_FILE);
Preconditions.checkArgument(keytabFilename != null &&
!keytabFilename.isEmpty(),
REST_KEYTAB_FILE + " should be set if security is enabled");
@@ -385,9 +388,14 @@ public class RESTServer implements Constants {
// Put up info server.
int port = conf.getInt("hbase.rest.info.port", 8085);
if (port >= 0) {
- conf.setLong("startcode", EnvironmentEdgeManager.currentTime());
- String a = conf.get("hbase.rest.info.bindAddress", "0.0.0.0");
- this.infoServer = new InfoServer("rest", a, port, false, conf);
+ final long startCode = EnvironmentEdgeManager.currentTime();
+ conf.setLong("startcode", startCode);
+ this.serverName = ServerName.valueOf(getHostName(conf), servicePort,
startCode);
+
+ String addr = conf.get("hbase.rest.info.bindAddress", "0.0.0.0");
+ this.infoServer = new InfoServer(REST_SERVER, addr, port, false, conf);
+ this.infoServer.addPrivilegedServlet("dump", "/dump",
RESTDumpServlet.class);
+ this.infoServer.setAttribute(REST_SERVER, this);
this.infoServer.setAttribute("hbase.conf", conf);
this.infoServer.start();
}
@@ -395,6 +403,11 @@ public class RESTServer implements Constants {
server.start();
}
+ private static String getHostName(Configuration conf) throws
UnknownHostException {
+ return Strings.domainNamePointerToHostName(DNS.getDefaultHost(
+ conf.get(REST_DNS_INTERFACE, "default"), conf.get(REST_DNS_NAMESERVER,
"default")));
+ }
+
public synchronized void join() throws Exception {
if (server == null) {
throw new IllegalStateException("Server is not running");
@@ -402,7 +415,19 @@ public class RESTServer implements Constants {
server.join();
}
+ private void stopInfoServer() {
+ if (this.infoServer != null) {
+ LOG.info("Stop info server");
+ try {
+ this.infoServer.stop();
+ } catch (Exception e) {
+ LOG.error("Failed to stop infoServer", e);
+ }
+ }
+ }
+
public synchronized void stop() throws Exception {
+ stopInfoServer();
if (server == null) {
throw new IllegalStateException("Server is not running");
}
@@ -426,6 +451,10 @@ public class RESTServer implements Constants {
return infoServer.getPort();
}
+ public ServerName getServerName() {
+ return serverName;
+ }
+
public Configuration getConf() {
return conf;
}
diff --git a/hbase-rest/src/main/resources/hbase-webapps/rest/footer.jsp
b/hbase-rest/src/main/resources/hbase-webapps/rest/footer.jsp
new file mode 100644
index 00000000000..a642ac36eff
--- /dev/null
+++ b/hbase-rest/src/main/resources/hbase-webapps/rest/footer.jsp
@@ -0,0 +1,32 @@
+<%--
+/**
+* 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.
+*/
+--%>
+
+ <script src="/static/js/jquery.min.js" type="text/javascript"></script>
+ <script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="/static/js/tab.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('div.navbar li.active').removeClass('active');
+ $('a[href="' + location.pathname +
'"]').closest('li').addClass('active');
+ });
+ </script>
+</body>
+</html>
+
diff --git a/hbase-rest/src/main/resources/hbase-webapps/rest/header.jsp
b/hbase-rest/src/main/resources/hbase-webapps/rest/header.jsp
new file mode 100644
index 00000000000..cb148a708c9
--- /dev/null
+++ b/hbase-rest/src/main/resources/hbase-webapps/rest/header.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="org.apache.hadoop.hbase.HBaseConfiguration"%>
+
+<!DOCTYPE html>
+<?xml version="1.0" encoding="UTF-8" ?>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title><%= request.getParameter("pageTitle")%></title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="">
+
+ <link href="/static/css/bootstrap.min.css" rel="stylesheet">
+ <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
+ <link href="/static/css/hbase.css" rel="stylesheet">
+</head>
+
+<body>
+<div class="navbar navbar-fixed-top navbar-default">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse"
data-target=".navbar-collapse">
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="navbar-brand" href="/rest.jsp"><img
src="/static/hbase_logo_small.png" alt="HBase Logo"/></a>
+ </div>
+ <div class="collapse navbar-collapse">
+ <ul class="nav navbar-nav">
+ <li class="active"><a href="/rest.jsp">Home</a></li>
+ <li><a href="/logs/">Local logs</a></li>
+ <li><a href="/processRest.jsp">Process Metrics</a></li>
+ <li><a href="/logLevel">Log Level</a></li>
+ <li><a href="/dump">Debug Dump</a></li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#"
id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
+ Metrics <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
+ <li><a target="_blank" href="/jmx">JMX</a></li>
+ <li><a target="_blank" href="/jmx?description=true">JMX with
description</a></li>
+ </ul>
+ </li>
+ <li><a href="/prof">Profiler</a></li>
+ <% if (HBaseConfiguration.isShowConfInServlet()) { %>
+ <li><a href="/conf">HBase Configuration</a></li>
+ <% } %>
+ </ul>
+ </div><!--/.nav-collapse -->
+ </div>
+</div>
+
diff --git a/hbase-rest/src/main/resources/hbase-webapps/rest/processRest.jsp
b/hbase-rest/src/main/resources/hbase-webapps/rest/processRest.jsp
new file mode 100644
index 00000000000..2b2d35fbfb3
--- /dev/null
+++ b/hbase-rest/src/main/resources/hbase-webapps/rest/processRest.jsp
@@ -0,0 +1,184 @@
+<%--
+/**
+ * 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.Date"
+ import="java.util.List"
+ import="javax.management.ObjectName"
+ import="java.lang.management.ManagementFactory"
+ import="java.lang.management.MemoryPoolMXBean"
+ import="java.lang.management.RuntimeMXBean"
+ import="java.lang.management.GarbageCollectorMXBean"
+ import="org.apache.hadoop.hbase.util.JSONMetricUtil"
+ import="org.apache.hadoop.hbase.procedure2.util.StringUtils"
+ import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix"
+%>
+
+<%
+RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
+ObjectName jvmMetrics = new ObjectName("Hadoop:service=HBase,name=JvmMetrics");
+
+// There is always two of GC collectors
+List<GarbageCollectorMXBean> gcBeans = JSONMetricUtil.getGcCollectorBeans();
+GarbageCollectorMXBean collector1 = null;
+GarbageCollectorMXBean collector2 = null;
+try {
+collector1 = gcBeans.get(0);
+collector2 = gcBeans.get(1);
+} catch(IndexOutOfBoundsException e) {}
+List<MemoryPoolMXBean> mPools = JSONMetricUtil.getMemoryPools();
+pageContext.setAttribute("pageTitle", "Process info for PID: " +
JSONMetricUtil.getProcessPID());
+%>
+
+<jsp:include page="header.jsp">
+ <jsp:param name="pageTitle" value="${pageTitle}"/>
+</jsp:include>
+
+<div class="container-fluid content">
+ <div class="row">
+ <div class="page-header">
+ <h1><%= JSONMetricUtil.getCommmand().split(" ")[0] %></h1>
+ </div>
+ </div>
+ <table class="table table-striped" width="90%" >
+ <tr>
+ <th>Started</th>
+ <th>Uptime</th>
+ <th>PID</th>
+ <th>Owner</th>
+ </tr>
+ <tr>
+ <tr>
+ <td><%= new Date(runtimeBean.getStartTime()) %></td>
+ <td><%= StringUtils.humanTimeDiff(runtimeBean.getUptime()) %></td>
+ <td><%= JSONMetricUtil.getProcessPID() %></td>
+ <td><%= runtimeBean.getSystemProperties().get("user.name") %></td>
+ </tr>
+ </table>
+</div>
+<div class="container-fluid content">
+ <div class="row">
+ <div class="page-header">
+ <h2>Threads</h2>
+ </div>
+ </div>
+ <table class="table table-striped" width="90%" >
+ <tr>
+ <th>ThreadsNew</th>
+ <th>ThreadsRunable</th>
+ <th>ThreadsBlocked</th>
+ <th>ThreadsWaiting</th>
+ <th>ThreadsTimeWaiting</th>
+ <th>ThreadsTerminated</th>
+ </tr>
+ <tr>
+ <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics, "ThreadsNew")
%></td>
+ <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics,
"ThreadsRunnable")%></td>
+ <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics,
"ThreadsBlocked")%></td>
+ <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics,
"ThreadsWaiting")%></td>
+ <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics,
"ThreadsTimedWaiting")%></td>
+ <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics,
"ThreadsTerminated")%></td>
+ </tr>
+ </table>
+</div>
+<div class="container-fluid content">
+ <div class="row">
+ <div class="page-header">
+ <h2>GC Collectors</h2>
+ </div>
+ </div>
+ <% if (gcBeans.size() == 2) { %>
+<div class="tabbable">
+ <ul class="nav nav-pills">
+ <li class="active">
+ <a href="#tab_gc1" data-toggle="tab"><%=collector1.getName() %></a>
+ </li>
+ <li class="">
+ <a href="#tab_gc2" data-toggle="tab"><%=collector2.getName() %></a>
+ </li>
+ </ul>
+ <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px
solid #ddd;">
+ <div class="tab-pane active" id="tab_gc1">
+ <table class="table table-striped">
+ <tr>
+ <th>Collection Count</th>
+ <th>Collection Time</th>
+ <th>Last duration</th>
+ </tr>
+ <tr>
+ <td> <%= collector1.getCollectionCount() %></td>
+ <td> <%=
StringUtils.humanTimeDiff(collector1.getCollectionTime()) %> </td>
+ <td> <%=
StringUtils.humanTimeDiff(JSONMetricUtil.getLastGcDuration(
+ collector1.getObjectName())) %></td>
+ </tr>
+ </table>
+ </div>
+ <div class="tab-pane" id="tab_gc2">
+ <table class="table table-striped">
+ <tr>
+ <th>Collection Count</th>
+ <th>Collection Time</th>
+ <th>Last duration</th>
+ </tr>
+ <tr>
+ <td> <%= collector2.getCollectionCount() %></td>
+ <td> <%= StringUtils.humanTimeDiff(collector2.getCollectionTime())
%> </td>
+ <td> <%=
StringUtils.humanTimeDiff(JSONMetricUtil.getLastGcDuration(
+ collector2.getObjectName())) %></td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
+ <%} else { %>
+ <p> Can not display GC Collector stats.</p>
+ <%} %>
+ Total GC Collection time: <%=
StringUtils.humanTimeDiff(collector1.getCollectionTime() +
+ collector2.getCollectionTime())%>
+</div>
+<% for(MemoryPoolMXBean mp:mPools) {
+if(mp.getName().contains("Cache")) continue;%>
+<div class="container-fluid content">
+ <div class="row">
+ <div class="page-header">
+ <h2><%= mp.getName() %></h2>
+ </div>
+ </div>
+ <table class="table table-striped" width="90%" >
+ <tr>
+ <th>Commited</th>
+ <th>Init</th>
+ <th>Max</th>
+ <th>Used</th>
+ <th>Utilization [%]</th>
+ </tr>
+ <tr>
+ <tr>
+ <td><%=
TraditionalBinaryPrefix.long2String(mp.getUsage().getCommitted(), "B", 1)
%></td>
+ <td><%= TraditionalBinaryPrefix.long2String(mp.getUsage().getInit(),
"B", 1) %></td>
+ <td><%= TraditionalBinaryPrefix.long2String(mp.getUsage().getMax(),
"B", 1) %></td>
+ <td><%= TraditionalBinaryPrefix.long2String(mp.getUsage().getUsed(),
"B", 1) %></td>
+ <td><%= JSONMetricUtil.calcPercentage(mp.getUsage().getUsed(),
+ mp.getUsage().getCommitted()) %></td>
+ </tr>
+ </table>
+</div>
+<% } %>
+
+<jsp:include page="footer.jsp" />
diff --git a/hbase-rest/src/main/resources/hbase-webapps/rest/rest.jsp
b/hbase-rest/src/main/resources/hbase-webapps/rest/rest.jsp
index 3deb2bbc735..ce6725f283a 100644
--- a/hbase-rest/src/main/resources/hbase-webapps/rest/rest.jsp
+++ b/hbase-rest/src/main/resources/hbase-webapps/rest/rest.jsp
@@ -18,60 +18,29 @@
*/
--%>
<%@ page contentType="text/html;charset=UTF-8"
- import="org.apache.hadoop.conf.Configuration"
- import="org.apache.hadoop.hbase.HBaseConfiguration"
- import="org.apache.hadoop.hbase.rest.model.VersionModel"
- import="org.apache.hadoop.hbase.util.VersionInfo"
- import="java.util.Date"%>
+ import="org.apache.hadoop.conf.Configuration"
+ import="org.apache.hadoop.hbase.rest.RESTServer"
+ import="org.apache.hadoop.hbase.rest.model.VersionModel"
+ import="org.apache.hadoop.hbase.util.VersionInfo"
+ import="java.util.Date"%>
+
<%
-Configuration conf =
(Configuration)getServletContext().getAttribute("hbase.conf");
-long startcode = conf.getLong("startcode", System.currentTimeMillis());
-String listenPort = conf.get("hbase.rest.port", "8080");
-%>
-<!DOCTYPE html>
-<?xml version="1.0" encoding="UTF-8" ?>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>HBase REST Server: <%= listenPort %></title>
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="description" content="">
+ Configuration conf = (Configuration)
getServletContext().getAttribute("hbase.conf");
+ long startcode = conf.getLong("startcode", System.currentTimeMillis());
- <link href="/static/css/bootstrap.min.css" rel="stylesheet">
- <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
- <link href="/static/css/hbase.css" rel="stylesheet">
- </head>
+ final RESTServer restServer = (RESTServer)
getServletContext().getAttribute(RESTServer.REST_SERVER);
+ final String hostName = restServer.getServerName().getHostname();
+ pageContext.setAttribute("pageTitle", "HBase REST Server" + hostName);
+%>
- <body>
- <div class="navbar navbar-fixed-top navbar-default">
- <div class="container-fluid">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle"
data-toggle="collapse" data-target=".navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="/rest.jsp"><img
src="/static/hbase_logo_small.png" alt="HBase Logo"/></a>
- </div>
- <div class="collapse navbar-collapse">
- <ul class="nav navbar-nav">
- <li class="active"><a href="/rest.jsp">Home</a></li>
- <li><a href="/logs/">Local logs</a></li>
- <li><a href="/logLevel">Log Level</a></li>
- <li><a href="/jmx">Metrics Dump</a></li>
- <li><a href="/prof">Profiler</a></li>
- <% if (HBaseConfiguration.isShowConfInServlet()) { %>
- <li><a href="/conf">HBase Configuration</a></li>
- <% } %>
- </ul>
- </div><!--/.nav-collapse -->
- </div>
- </div>
+<jsp:include page="header.jsp">
+ <jsp:param name="pageTitle" value="${pageTitle}"/>
+</jsp:include>
<div class="container-fluid content">
<div class="row inner_header">
<div class="page-header">
- <h1>RESTServer <small><%= listenPort %></small></h1>
+ <h1>RESTServer <small><%= hostName %></small></h1>
</div>
</div>
<div class="row">
@@ -114,9 +83,6 @@ String listenPort = conf.get("hbase.rest.port", "8080");
</section>
</div>
</div>
-<script src="/static/js/jquery.min.js" type="text/javascript"></script>
-<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
-<script src="/static/js/tab.js" type="text/javascript"></script>
-</body>
-</html>
+
+<jsp:include page="footer.jsp" />
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 863d7e039a4..886be7801a2 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
@@ -162,7 +162,15 @@ AssignmentManager assignmentManager =
master.getAssignmentManager();
<li><a href="/logs/">Local Logs</a></li>
<li><a href="/logLevel">Log Level</a></li>
<li><a href="/dump">Debug Dump</a></li>
- <li><a href="/jmx">Metrics Dump</a></li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#"
id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
+ Metrics <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu"
aria-labelledby="navbarDropdownMenuLink">
+ <li><a target="_blank" href="/jmx">JMX</a></li>
+ <li><a target="_blank" href="/jmx?description=true">JMX
with description</a></li>
+ </ul>
+ </li>
<li><a href="/prof">Profiler</a></li>
<%if HBaseConfiguration.isShowConfInServlet()%>
<li><a href="/conf">HBase Configuration</a></li>
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 2068c760799..63054c92348 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
@@ -114,7 +114,15 @@ org.apache.hadoop.hbase.zookeeper.MasterAddressTracker;
<li><a href="/rsOperationDetails.jsp">Operation
Details</a></li>
<li><a href="/logLevel">Log Level</a></li>
<li><a href="/dump">Debug Dump</a></li>
- <li><a href="/jmx">Metrics Dump</a></li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#"
id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
+ Metrics <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu"
aria-labelledby="navbarDropdownMenuLink">
+ <li><a target="_blank" href="/jmx">JMX</a></li>
+ <li><a target="_blank" href="/jmx?description=true">JMX
with description</a></li>
+ </ul>
+ </li>
<li><a href="/prof">Profiler</a></li>
<%if HBaseConfiguration.isShowConfInServlet()%>
<li><a href="/conf">HBase Configuration</a></li>
@@ -289,7 +297,12 @@ $(document).ready(function()
type: "numeric"
});
- $("#baseStatsTable").tablesorter();
+ $("#baseStatsTable").tablesorter({
+ headers: {
+ 1: {empty: 'emptyMin'},
+ 2: {empty: 'emptyMax'}
+ }
+ });
$("#requestStatsTable").tablesorter({
headers: {
1: {sorter: 'separator'},
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 7f4fa55f59d..dac6be4fc5a 100644
--- a/hbase-server/src/main/resources/hbase-webapps/master/header.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/master/header.jsp
@@ -69,7 +69,15 @@
<li><a href="/logs/">Local Logs</a></li>
<li><a href="/logLevel">Log Level</a></li>
<li><a href="/dump">Debug Dump</a></li>
- <li><a href="/jmx">Metrics Dump</a></li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#"
id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
+ Metrics <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu"
aria-labelledby="navbarDropdownMenuLink">
+ <li><a target="_blank" href="/jmx">JMX</a></li>
+ <li><a target="_blank" href="/jmx?description=true">JMX with
description</a></li>
+ </ul>
+ </li>
<li><a href="/prof">Profiler</a></li>
<% if (HBaseConfiguration.isShowConfInServlet()) { %>
<li><a href="/conf">HBase Configuration</a></li>
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
index 8b88f20301d..6ae98b6985e 100644
--- a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
@@ -93,7 +93,7 @@
* its region server.
* @return an anchor tag if one can be built, {@code null} otherwise.
*/
- private static String buildRegionServerLink(final ServerName serverName,
final int rsInfoPort,
+ private static String buildRegionLink(final ServerName serverName, final int
rsInfoPort,
final RegionInfo regionInfo, final RegionState.State regionState) {
if (serverName == null || regionInfo == null) { return null; }
@@ -107,15 +107,74 @@
+ "?name=" + regionInfo.getEncodedName();
return "<a href=\"" + URI + "\">" + serverName.getServerName() + "</a>";
}
+
+ /**
+ * Render an <td> tag contents server name which the given region deploys.
+ * Links to the server rs-status page.
+ * <td class="undeployed-region">not deployed</td> instead if can not find
the deploy message.
+ * @return an <td> tag contents server name links to server rs-status page.
+ */
+ private static String buildRegionDeployedServerTag(RegionInfo regionInfo,
HMaster master,
+ Map<RegionInfo, ServerName> regionsToServer) {
+ ServerName serverName = regionsToServer.get(regionInfo);
+
+ if (serverName == null) {
+ return "<td class=\"undeployed-region\">not deployed</td>";
+ }
+
+ String hostName = serverName.getHostname();
+ String hostNameEncoded = URLEncoder.encode(hostName);
+ // This port might be wrong if RS actually ended up using something else.
+ int serverInfoPort = master.getRegionServerInfoPort(serverName);
+ String urlRegionServer = "//" + hostNameEncoded + ":" + serverInfoPort +
"/rs-status";
+
+ return "<td><a href=\"" + urlRegionServer + "\">" +
StringEscapeUtils.escapeHtml4(hostName)
+ + ":" + serverInfoPort + "</a></td>";
+ }
+
+ /**
+ * @return an <p> tag guide user to see all region messages.
+ */
+ private static String moreRegionsToRender(int numRegionsRendered, int
numRegions, String fqtn) {
+ if (numRegions > numRegionsRendered) {
+ String allRegionsUrl = "?name=" + URLEncoder.encode(fqtn) +
"&numRegions=all";
+
+ return "This table has <b>" + numRegions
+ + "</b> regions in total, in order to improve the page load time, only
<b>"
+ + numRegionsRendered + "</b> regions are displayed here, <a href=\""
+ + allRegionsUrl + "\">click here</a> to see all regions.</p>";
+ }
+ return "";
+ }
%>
+
+<jsp:include page="header.jsp">
+ <jsp:param name="pageTitle" value="${pageTitle}"/>
+</jsp:include>
+
<%
final String ZEROMB = "0 MB";
HMaster master = (HMaster)getServletContext().getAttribute(HMaster.MASTER);
Configuration conf = master.getConfiguration();
String fqtn = request.getParameter("name");
+ // handle the case for fqtn is null or master is not initialized with error
message + redirect
+ if (fqtn == null || !master.isInitialized()) {
+%>
+ <div class="container-fluid content">
+ <div class="row inner_header">
+ <div class="page-header">
+ <h1>Table not ready</h1>
+ </div>
+ </div>
+ <p><hr><p>
+ <jsp:include page="redirect.jsp" />
+ </div>
+<% return;
+ } %>
+
+<%
final String escaped_fqtn = StringEscapeUtils.escapeHtml4(fqtn);
- Table table;
- boolean withReplica = false;
+ Table table = master.getConnection().getTable(TableName.valueOf(fqtn));
boolean showFragmentation =
conf.getBoolean("hbase.master.ui.fragmentation.enabled", false);
boolean readOnly = !InfoServer.canUserModifyUI(request, getServletContext(),
conf);
int numMetaReplicas =
@@ -162,35 +221,50 @@
final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
%>
-<jsp:include page="header.jsp">
- <jsp:param name="pageTitle" value="${pageTitle}"/>
-</jsp:include>
-
-<%
- if (fqtn != null && master.isInitialized()) {
- try {
- table = master.getConnection().getTable(TableName.valueOf(fqtn));
- if (table.getTableDescriptor().getRegionReplication() > 1) {
- withReplica = true;
- }
- if ( !readOnly && action != null ) {
-%>
-<div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table action request accepted</h1>
+<% // unknow table
+ if (! admin.tableExists(TableName.valueOf(fqtn)).get()) { %>
+ <div class="container-fluid content">
+ <div class="row inner_header">
+ <div class="page-header">
+ <h1>Table not found</h1>
+ </div>
+ </div>
+ <p><hr><p>
+ <jsp:include page="redirect.jsp" />
</div>
- </div>
- <p><hr><p>
- <%
- if (action.equals("split")) {
+<% return;
+ } %>
+
+<% // table split/major compact/compact/merge actions
+ if ( !readOnly && action != null ) { %>
+ <div class="container-fluid content">
+ <div class="row inner_header">
+ <div class="page-header">
+ <h1>Table action request accepted</h1>
+ </div>
+ </div>
+ <p><hr><p>
+<% if (action.equals("split")) {
if (key != null && key.length() > 0) {
admin.split(TableName.valueOf(fqtn), Bytes.toBytes(key));
} else {
admin.split(TableName.valueOf(fqtn));
}
+%> Split request accepted. <%
+ } else if (action.equals("major compact")) {
+ if (key != null && key.length() > 0) {
+ List<RegionInfo> regions =
admin.getRegions(TableName.valueOf(fqtn)).get();
+ byte[] row = Bytes.toBytes(key);
- %> Split request accepted. <%
+ for (RegionInfo region : regions) {
+ if (region.containsRow(row)) {
+ admin.majorCompactRegion(region.getRegionName());
+ }
+ }
+ } else {
+ admin.majorCompact(TableName.valueOf(fqtn));
+ }
+%> major Compact request accepted. <%
} else if (action.equals("compact")) {
if (key != null && key.length() > 0) {
List<RegionInfo> regions =
admin.getRegions(TableName.valueOf(fqtn)).get();
@@ -204,239 +278,229 @@
} else {
admin.compact(TableName.valueOf(fqtn));
}
- %> Compact request accepted. <%
+%> Compact request accepted. <%
} else if (action.equals("merge")) {
- if (left != null && left.length() > 0 && right != null &&
right.length() > 0) {
- admin.mergeRegions(Bytes.toBytesBinary(left),
Bytes.toBytesBinary(right), false);
- }
- %> Merge request accepted. <%
- }
-%>
- <jsp:include page="redirect.jsp" />
-</div>
-<%
-} else {
-%>
-<div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table <small><%= escaped_fqtn %></small></h1>
+ if (left != null && left.length() > 0 && right != null && right.length()
> 0) {
+ admin.mergeRegions(Bytes.toBytesBinary(left),
Bytes.toBytesBinary(right), false);
+ }
+%> Merge request accepted. <%
+ } %>
+ <jsp:include page="redirect.jsp" />
</div>
+<% return;
+ } %>
+
+<div class="container-fluid content">
+<div class="row inner_header">
+ <div class="page-header">
+ <h1>Table <small><%= escaped_fqtn %></small></h1>
</div>
- <div class="row">
- <%
- if(fqtn.equals(TableName.META_TABLE_NAME.getNameAsString())) {
- %>
- <h2>Table Regions</h2>
- <div class="tabbable">
- <ul class="nav nav-pills">
- <li class="active">
- <a href="#metaTab_baseStats" data-toggle="tab">Base Stats</a>
- </li>
- <li class="">
- <a href="#metaTab_localityStats" data-toggle="tab">Localities</a>
- </li>
- <li class="">
- <a href="#metaTab_compactStats" data-toggle="tab">Compactions</a>
- </li>
- </ul>
- <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px
solid #ddd;">
- <div class="tab-pane active" id="metaTab_baseStats">
- <table id="tableRegionTable" class="tablesorter table table-striped">
- <thead>
- <tr>
- <th>Name</th>
- <th>Region Server</th>
- <th>ReadRequests</th>
- <th>WriteRequests</th>
- <th>StorefileSize</th>
- <th>Num.Storefiles</th>
- <th>MemSize</th>
- <th>Start Key</th>
- <th>End Key</th>
- <%
- if (withReplica) {
- %>
- <th>ReplicaID</th>
- <%
- }
- %>
- </tr>
- </thead>
- <tbody>
- <%
- // NOTE: Presumes meta with one or more replicas
- for (int j = 0; j < numMetaReplicas; j++) {
- RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
- RegionInfoBuilder.FIRST_META_REGIONINFO, j);
- //If a metaLocation is null, All of its info would be empty
here to be displayed.
- RegionStateNode rsn =
master.getAssignmentManager().getRegionStates()
- .getRegionStateNode(meta);
- ServerName metaLocation = rsn != null ?
rsn.getRegionLocation() : null;
- for (int i = 0; i < 1; i++) {
- //If metaLocation is null, default value below would be
displayed in UI.
- String hostAndPort = "";
- String readReq = "N/A";
- String writeReq = "N/A";
- String fileSize = ZEROMB;
- String fileCount = "N/A";
- String memSize = ZEROMB;
- if (metaLocation != null) {
- ServerMetrics sl =
master.getServerManager().getLoad(metaLocation);
- // The host name portion should be safe, but I don't know
how we handle IDNs so err on the side of failing safely.
- hostAndPort =
URLEncoder.encode(metaLocation.getHostname()) + ":" +
master.getRegionServerInfoPort(metaLocation);
- if (sl != null) {
- Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
- if (map.containsKey(meta.getRegionName())) {
- RegionMetrics load = map.get(meta.getRegionName());
- readReq = String.format("%,1d",
load.getReadRequestCount());
- writeReq = String.format("%,1d",
load.getWriteRequestCount());
- double rSize =
load.getStoreFileSize().get(Size.Unit.BYTE);
- if (rSize > 0) {
- fileSize = StringUtils.byteDesc((long) rSize);
- }
- fileCount = String.format("%,1d",
load.getStoreFileCount());
- double mSize =
load.getMemStoreSize().get(Size.Unit.BYTE);
- if (mSize > 0) {
- memSize = StringUtils.byteDesc((long)mSize);
- }
- }
+</div>
+
+<div class="row">
+<% //Meta table.
+ if(fqtn.equals(TableName.META_TABLE_NAME.getNameAsString())) { %>
+<h2>Table Regions</h2>
+<div class="tabbable">
+ <ul class="nav nav-pills">
+ <li class="active"><a href="#metaTab_baseStats" data-toggle="tab">Base
Stats</a></li>
+ <li class=""><a href="#metaTab_localityStats"
data-toggle="tab">Localities</a></li>
+ <li class=""><a href="#metaTab_compactStats"
data-toggle="tab">Compactions</a></li>
+ </ul>
+
+ <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px
solid #ddd;">
+ <div class="tab-pane active" id="metaTab_baseStats">
+ <table id="metaTableBaseStatsTable" class="tablesorter table
table-striped">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Region Server</th>
+ <th>ReadRequests</th>
+ <th>WriteRequests</th>
+ <th>Uncompressed StoreFileSize</th>
+ <th>StorefileSize</th>
+ <th>Num.Storefiles</th>
+ <th>MemSize</th>
+ <th>Start Key</th>
+ <th>End Key</th>
+ <th>ReplicaID</th>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ // NOTE: Presumes meta with one or more replicas
+ for (int j = 0; j < numMetaReplicas; j++) {
+ RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
+ RegionInfoBuilder.FIRST_META_REGIONINFO, j);
+ //If a metaLocation is null, All of its info would be empty here
to be displayed.
+ RegionStateNode rsn =
master.getAssignmentManager().getRegionStates()
+ .getRegionStateNode(meta);
+ ServerName metaLocation = rsn != null ? rsn.getRegionLocation() :
null;
+ for (int i = 0; i < 1; i++) {
+ //If metaLocation is null, default value below would be
displayed in UI.
+ String hostAndPort = "";
+ String readReq = "N/A";
+ String writeReq = "N/A";
+ String fileSizeUncompressed = ZEROMB;
+ String fileSize = ZEROMB;
+ String fileCount = "N/A";
+ String memSize = ZEROMB;
+ if (metaLocation != null) {
+ ServerMetrics sl =
master.getServerManager().getLoad(metaLocation);
+ // The host name portion should be safe, but I don't know how
we handle IDNs so err on the side of failing safely.
+ hostAndPort = URLEncoder.encode(metaLocation.getHostname()) +
":" + master.getRegionServerInfoPort(metaLocation);
+ if (sl != null) {
+ Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
+ if (map.containsKey(meta.getRegionName())) {
+ RegionMetrics load = map.get(meta.getRegionName());
+ readReq = String.format("%,1d",
load.getReadRequestCount());
+ writeReq = String.format("%,1d",
load.getWriteRequestCount());
+ double rSize = load.getStoreFileSize().get(Size.Unit.BYTE);
+ if (rSize > 0) {
+ fileSize = StringUtils.byteDesc((long) rSize);
+ }
+ double rSizeUncompressed =
load.getUncompressedStoreFileSize().get(Size.Unit.BYTE);
+ if (rSizeUncompressed > 0) {
+ fileSizeUncompressed = StringUtils.byteDesc((long)
rSizeUncompressed);
+ }
+ fileCount = String.format("%,1d",
load.getStoreFileCount());
+ double mSize = load.getMemStoreSize().get(Size.Unit.BYTE);
+ if (mSize > 0) {
+ memSize = StringUtils.byteDesc((long)mSize);
}
}
- %>
- <tr>
- <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
- <td><a href="http://<%= hostAndPort %>/rs-status"><%=
StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
- <td><%= readReq%></td>
- <td><%= writeReq%></td>
- <td><%= fileSize%></td>
- <td><%= fileCount%></td>
- <td><%= memSize%></td>
- <td><%= escapeXml(Bytes.toString(meta.getStartKey())) %></td>
- <td><%= escapeXml(Bytes.toString(meta.getEndKey())) %></td>
- <%
- if (withReplica) {
- %>
- <td><%= meta.getReplicaId() %></td>
- <%
}
- %>
- </tr>
- <% } %>
- <%} %>
- </tbody>
- </table>
- </div>
- <div class="tab-pane" id="metaTab_localityStats">
- <table id="tableRegionTable" class="tablesorter table
table-striped">
- <thead>
- <tr>
- <th>Name</th>
- <th>Region Server</th>
- <th>Locality</th>
- <th>LocalityForSsd</th>
- </tr>
- </thead>
- <tbody>
- <%
- // NOTE: Presumes meta with one or more replicas
- for (int j = 0; j < numMetaReplicas; j++) {
- RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
-
RegionInfoBuilder.FIRST_META_REGIONINFO, j);
- //If a metaLocation is null, All of its info would be empty
here to be displayed.
- RegionStateNode rsn =
master.getAssignmentManager().getRegionStates()
- .getRegionStateNode(meta);
- ServerName metaLocation = rsn != null ?
rsn.getRegionLocation() : null;
- for (int i = 0; i < 1; i++) {
- //If metaLocation is null, default value below would be
displayed in UI.
- String hostAndPort = "";
- float locality = 0.0f;
- float localityForSsd = 0.0f;
- if (metaLocation != null) {
- ServerMetrics sl =
master.getServerManager().getLoad(metaLocation);
- hostAndPort =
URLEncoder.encode(metaLocation.getHostname()) + ":" +
master.getRegionServerInfoPort(metaLocation);
- if (sl != null) {
- Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
- if (map.containsKey(meta.getRegionName())) {
- RegionMetrics load = map.get(meta.getRegionName());
- locality = load.getDataLocality();
- localityForSsd = load.getDataLocalityForSsd();
- }
- }
+ }
+ %>
+ <tr>
+ <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
+ <td><a href="http://<%= hostAndPort %>/rs-status"><%=
StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
+ <td><%= readReq%></td>
+ <td><%= writeReq%></td>
+ <td><%= fileSizeUncompressed%></td>
+ <td><%= fileSize%></td>
+ <td><%= fileCount%></td>
+ <td><%= memSize%></td>
+ <td><%= escapeXml(Bytes.toString(meta.getStartKey())) %></td>
+ <td><%= escapeXml(Bytes.toString(meta.getEndKey())) %></td>
+ <td><%= meta.getReplicaId() %></td>
+ </tr>
+ <% } %>
+ <%} %>
+ </tbody>
+ </table>
+ </div>
+ <div class="tab-pane" id="metaTab_localityStats">
+ <table id="metaTableLocalityStatsTable" class="tablesorter table
table-striped">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Region Server</th>
+ <th>Locality</th>
+ <th>LocalityForSsd</th>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ // NOTE: Presumes meta with one or more replicas
+ for (int j = 0; j < numMetaReplicas; j++) {
+ RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
+ RegionInfoBuilder.FIRST_META_REGIONINFO,
j);
+ //If a metaLocation is null, All of its info would be empty here
to be displayed.
+ RegionStateNode rsn =
master.getAssignmentManager().getRegionStates()
+ .getRegionStateNode(meta);
+ ServerName metaLocation = rsn != null ? rsn.getRegionLocation() :
null;
+ for (int i = 0; i < 1; i++) {
+ //If metaLocation is null, default value below would be
displayed in UI.
+ String hostAndPort = "";
+ float locality = 0.0f;
+ float localityForSsd = 0.0f;
+ if (metaLocation != null) {
+ ServerMetrics sl =
master.getServerManager().getLoad(metaLocation);
+ hostAndPort = URLEncoder.encode(metaLocation.getHostname()) +
":" + master.getRegionServerInfoPort(metaLocation);
+ if (sl != null) {
+ Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
+ if (map.containsKey(meta.getRegionName())) {
+ RegionMetrics load = map.get(meta.getRegionName());
+ locality = load.getDataLocality();
+ localityForSsd = load.getDataLocalityForSsd();
}
- %>
- <tr>
- <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
- <td><a href="http://<%= hostAndPort %>/rs-status"><%=
StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
- <td><%= locality%></td>
- <td><%= localityForSsd%></td>
- </tr>
- <% } %>
- <%} %>
- </tbody>
- </table>
- </div>
- <div class="tab-pane" id="metaTab_compactStats">
- <table id="metaTableCompactStatsTable" class="tablesorter table
table-striped">
- <thead>
- <tr>
- <th>Name</th>
- <th>Region Server</th>
- <th>Num. Compacting Cells</th>
- <th>Num. Compacted Cells</th>
- <th>Remaining Cells</th>
- <th>Compaction Progress</th>
- </tr>
- </thead>
- <tbody>
- <%
- // NOTE: Presumes meta with one or more replicas
- for (int j = 0; j < numMetaReplicas; j++) {
- RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
+ }
+ }
+ %>
+ <tr>
+ <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
+ <td><a href="http://<%= hostAndPort %>/rs-status"><%=
StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
+ <td><%= locality%></td>
+ <td><%= localityForSsd%></td>
+ </tr>
+ <% } %>
+ <%} %>
+ </tbody>
+ </table>
+ </div>
+ <div class="tab-pane" id="metaTab_compactStats">
+ <table id="metaTableCompactStatsTable" class="tablesorter table
table-striped">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Region Server</th>
+ <th>Num. Compacting Cells</th>
+ <th>Num. Compacted Cells</th>
+ <th>Remaining Cells</th>
+ <th>Compaction Progress</th>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ // NOTE: Presumes meta with one or more replicas
+ for (int j = 0; j < numMetaReplicas; j++) {
+ RegionInfo meta = RegionReplicaUtil.getRegionInfoForReplica(
RegionInfoBuilder.FIRST_META_REGIONINFO, j);
- //If a metaLocation is null, All of its info would be empty
here to be displayed.
- RegionStateNode rsn =
master.getAssignmentManager().getRegionStates()
- .getRegionStateNode(meta);
- ServerName metaLocation = rsn != null ?
rsn.getRegionLocation() : null;
- for (int i = 0; i < 1; i++) {
- //If metaLocation is null, default value below would be
displayed in UI.
- String hostAndPort = "";
- long compactingCells = 0;
- long compactedCells = 0;
- String compactionProgress = "";
- if (metaLocation != null) {
- ServerMetrics sl =
master.getServerManager().getLoad(metaLocation);
- hostAndPort =
URLEncoder.encode(metaLocation.getHostname()) + ":" +
master.getRegionServerInfoPort(metaLocation);
- if (sl != null) {
- Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
- if (map.containsKey(meta.getRegionName())) {
- RegionMetrics load = map.get(meta.getRegionName());
- compactingCells = load.getCompactingCellCount();
- compactedCells = load.getCompactedCellCount();
- if (compactingCells > 0) {
- compactionProgress = String.format("%.2f", 100 *
((float)
- compactedCells / compactingCells)) + "%";
- }
- }
+ //If a metaLocation is null, All of its info would be empty here
to be displayed.
+ RegionStateNode rsn =
master.getAssignmentManager().getRegionStates()
+ .getRegionStateNode(meta);
+ ServerName metaLocation = rsn != null ? rsn.getRegionLocation() :
null;
+ for (int i = 0; i < 1; i++) {
+ //If metaLocation is null, default value below would be
displayed in UI.
+ String hostAndPort = "";
+ long compactingCells = 0;
+ long compactedCells = 0;
+ String compactionProgress = "";
+ if (metaLocation != null) {
+ ServerMetrics sl =
master.getServerManager().getLoad(metaLocation);
+ hostAndPort = URLEncoder.encode(metaLocation.getHostname()) +
":" + master.getRegionServerInfoPort(metaLocation);
+ if (sl != null) {
+ Map<byte[], RegionMetrics> map = sl.getRegionMetrics();
+ if (map.containsKey(meta.getRegionName())) {
+ RegionMetrics load = map.get(meta.getRegionName());
+ compactingCells = load.getCompactingCellCount();
+ compactedCells = load.getCompactedCellCount();
+ if (compactingCells > 0) {
+ compactionProgress = String.format("%.2f", 100 * ((float)
+ compactedCells / compactingCells)) + "%";
}
}
- %>
- <tr>
- <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
- <td><a href="http://<%= hostAndPort %>/rs-status"><%=
StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
- <td><%= String.format("%,1d", compactingCells)%></td>
- <td><%= String.format("%,1d", compactedCells)%></td>
- <td><%= String.format("%,1d", compactingCells -
compactedCells)%></td>
- <td><%= compactionProgress%></td>
- </tr>
- <% } %>
- <%} %>
- </tbody>
- </table>
- </div>
- </div>
+ }
+ }
+ %>
+ <tr>
+ <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
+ <td><a href="http://<%= hostAndPort %>/rs-status"><%=
StringEscapeUtils.escapeHtml4(hostAndPort) %></a></td>
+ <td><%= String.format("%,1d", compactingCells)%></td>
+ <td><%= String.format("%,1d", compactedCells)%></td>
+ <td><%= String.format("%,1d", compactingCells -
compactedCells)%></td>
+ <td><%= compactionProgress%></td>
+ </tr>
+ <% } %>
+ <%} %>
+ </tbody>
+ </table>
</div>
- <h2 id="meta-entries">Meta Entries</h2>
+ </div>
+</div>
+
+<h2 id="meta-entries">Meta Entries</h2>
<%
if (!metaBrowser.getErrorMessages().isEmpty()) {
for (final String errorMessage : metaBrowser.getErrorMessages()) {
@@ -504,6 +568,7 @@
final RegionInfo regionInfo = regionReplicaInfo.getRegionInfo();
final ServerName serverName = regionReplicaInfo.getServerName();
final RegionState.State regionState = regionReplicaInfo.getRegionState();
+ final int rsPort = master.getRegionServerInfoPort(serverName);
final long seqNum = regionReplicaInfo.getSeqNum();
@@ -521,21 +586,21 @@
splitRegions.entrySet().stream()
.map(entry -> String.format(regionSpanFormat, entry.getKey(),
entry.getValue().getRegionNameAsString()))
.collect(Collectors.joining("<br/>"));
-%>
- <tr>
- <td title="<%= regionInfoColumnName %>"><%= regionNameDisplay %></td>
- <td title="startKey"><%= startKeyDisplay %></td>
- <td title="endKey"><%= endKeyDisplay %></td>
- <td title="replicaId"><%= replicaIdDisplay %></td>
- <td title="regionState"><%= regionStateDisplay %></td>
- <td title="<%= serverColumnName + "," + startCodeColumnName %>"><%=
serverName != null ? buildRegionServerLink(serverName,
master.getRegionServerInfoPort(serverName), regionInfo, regionState) : ""
%></td>
- <td title="<%= seqNumColumnName %>"><%= seqNum %></td>
- <td title="<%= serverNameColumnName %>"><%= targetServerName %></td>
- <td><%= mergeRegionNames %></td>
- <td><%= splitName %></td>
- </tr>
-<%
- }
+ %>
+ <tr>
+ <td title="<%= regionInfoColumnName %>"><%= regionNameDisplay %></td>
+ <td title="startKey"><%= startKeyDisplay %></td>
+ <td title="endKey"><%= endKeyDisplay %></td>
+ <td title="replicaId"><%= replicaIdDisplay %></td>
+ <td title="regionState"><%= regionStateDisplay %></td>
+ <td title="<%= serverColumnName + "," + startCodeColumnName %>"><%=
buildRegionLink(serverName, rsPort, regionInfo, regionState) %></td>
+ <td title="<%= seqNumColumnName %>"><%= seqNum %></td>
+ <td title="<%= serverNameColumnName %>"><%= targetServerName %></td>
+ <td><%= mergeRegionNames %></td>
+ <td><%= splitName %></td>
+ </tr>
+ <%
+ }
metaScanHasMore = results.hasMoreResults();
}
@@ -588,555 +653,491 @@
<%
}
%>
- </select>
- <button type="submit" class="btn btn-primary"
style="display:inline; width:auto">
- Filter Results
- </button>
- </div>
- </form>
+ </select>
+ <button type="submit" class="btn btn-primary" style="display:inline;
width:auto">
+ Filter Results
+ </button>
</div>
- </div>
- <%} else {
- RegionStates states = master.getAssignmentManager().getRegionStates();
- Map<RegionState.State, List<RegionInfo>> regionStates =
states.getRegionByStateOfTable(table.getName());
- Map<String, RegionState.State> stateMap = new HashMap<>();
- for (RegionState.State regionState : regionStates.keySet()) {
- for (RegionInfo regionInfo : regionStates.get(regionState)) {
- stateMap.put(regionInfo.getEncodedName(), regionState);
- }
+ </form>
+ </div>
+</div>
+<%} else {
+ //Common tables
+ RegionStates states = master.getAssignmentManager().getRegionStates();
+ Map<RegionState.State, List<RegionInfo>> regionStates =
states.getRegionByStateOfTable(table.getName());
+ Map<String, RegionState.State> stateMap = new HashMap<>();
+ for (RegionState.State regionState : regionStates.keySet()) {
+ for (RegionInfo regionInfo : regionStates.get(regionState)) {
+ stateMap.put(regionInfo.getEncodedName(), regionState);
+ }
+ }
+ RegionLocator r = master.getConnection().getRegionLocator(table.getName());
+
+ try {
+%>
+<h2>Table Attributes</h2>
+<table class="table table-striped">
+ <tr>
+ <th>Attribute Name</th>
+ <th>Value</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>Enabled</td>
+ <td><%= master.getTableStateManager().isTableState(table.getName(),
TableState.State.ENABLED) %></td>
+ <td>Is the table enabled</td>
+ </tr>
+ <tr>
+ <td>Compaction</td>
+ <td>
+<%
+ if (master.getTableStateManager().isTableState(table.getName(),
TableState.State.ENABLED)) {
+ CompactionState compactionState =
master.getCompactionState(table.getName());
+ %><%= compactionState==null?"UNKNOWN":compactionState %><%
+ } else {
+ %><%= CompactionState.NONE %><%
+ }
+%>
+ </td>
+ <td>Is the table compacting</td>
+ </tr>
+<% if (showFragmentation) { %>
+ <tr>
+ <td>Fragmentation</td>
+ <td><%= frags.get(fqtn) != null ? frags.get(fqtn).intValue() + "%" :
"n/a" %></td>
+ <td>How fragmented is the table. After a major compaction it is 0%.</td>
+ </tr>
+<% } %>
+<%
+ if (quotasEnabled) {
+ TableName tn = TableName.valueOf(fqtn);
+ SpaceQuotaSnapshot masterSnapshot = null;
+ Quotas quota = QuotaTableUtil.getTableQuota(master.getConnection(), tn);
+ if (quota == null || !quota.hasSpace()) {
+ quota = QuotaTableUtil.getNamespaceQuota(master.getConnection(),
tn.getNamespaceAsString());
+ if (quota != null) {
+ masterSnapshot =
master.getQuotaObserverChore().getNamespaceQuotaSnapshots()
+ .get(tn.getNamespaceAsString());
}
- RegionLocator r =
master.getConnection().getRegionLocator(table.getName());
- try { %>
- <h2>Table Attributes</h2>
- <table class="table table-striped">
- <tr>
- <th>Attribute Name</th>
- <th>Value</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>Enabled</td>
- <td><%= master.getTableStateManager().isTableState(table.getName(),
TableState.State.ENABLED) %></td>
- <td>Is the table enabled</td>
- </tr>
- <tr>
- <td>Compaction</td>
- <td>
- <%
- if (master.getTableStateManager().isTableState(table.getName(),
TableState.State.ENABLED)) {
- CompactionState compactionState =
master.getCompactionState(table.getName());
- %><%= compactionState==null?"UNKNOWN":compactionState %><%
- } else {
- %><%= CompactionState.NONE %><%
- }
- %>
- </td>
- <td>Is the table compacting</td>
- </tr>
- <% if (showFragmentation) { %>
- <tr>
- <td>Fragmentation</td>
- <td><%= frags.get(fqtn) != null ? frags.get(fqtn).intValue() + "%" :
"n/a" %></td>
- <td>How fragmented is the table. After a major compaction it is
0%.</td>
- </tr>
- <% } %>
- <%
- if (quotasEnabled) {
- TableName tn = TableName.valueOf(fqtn);
- SpaceQuotaSnapshot masterSnapshot = null;
- Quotas quota = QuotaTableUtil.getTableQuota(master.getConnection(),
tn);
- if (quota == null || !quota.hasSpace()) {
- quota = QuotaTableUtil.getNamespaceQuota(master.getConnection(),
tn.getNamespaceAsString());
- if (quota != null) {
- masterSnapshot =
master.getQuotaObserverChore().getNamespaceQuotaSnapshots()
- .get(tn.getNamespaceAsString());
- }
- } else {
- masterSnapshot =
master.getQuotaObserverChore().getTableQuotaSnapshots().get(tn);
- }
- if (quota != null && quota.hasSpace()) {
- SpaceQuota spaceQuota = quota.getSpace();
- %>
- <tr>
- <td>Space Quota</td>
- <td>
- <table>
- <tr>
- <th>Property</th>
- <th>Value</th>
- </tr>
- <tr>
- <td>Limit</td>
- <td><%= StringUtils.byteDesc(spaceQuota.getSoftLimit()) %></td>
- </tr>
- <tr>
- <td>Policy</td>
- <td><%= spaceQuota.getViolationPolicy() %></td>
- </tr>
- <%
- if (masterSnapshot != null) {
- %>
- <tr>
- <td>Usage</td>
- <td><%= StringUtils.byteDesc(masterSnapshot.getUsage()) %></td>
- </tr>
- <tr>
- <td>State</td>
- <td><%= masterSnapshot.getQuotaStatus().isInViolation() ? "In
Violation" : "In Observance" %></td>
- </tr>
- <%
- }
- %>
- </table>
- </td>
- <td>Information about a Space Quota on this table, if set.</td>
- </tr>
- <%
- }
- if (quota != null && quota.hasThrottle()) {
- List<ThrottleSettings> throttles =
QuotaSettingsFactory.fromTableThrottles(table.getName(), quota.getThrottle());
- if (throttles.size() > 0) {
- %>
- <tr>
- <td>Throttle Quota</td>
- <td>
- <table>
- <tr>
- <th>Limit</th>
- <th>Type</th>
- <th>TimeUnit</th>
- <th>Scope</th>
- </tr>
- <%
- for (ThrottleSettings throttle : throttles) {
- %>
- <tr>
- <td><%= throttle.getSoftLimit() %></td>
- <td><%= throttle.getThrottleType() %></td>
- <td><%= throttle.getTimeUnit() %></td>
- <td><%= throttle.getQuotaScope() %></td>
- </tr>
- <%
- }
- %>
- </table>
- </td>
- <td>Information about a Throttle Quota on this table, if set.</td>
- </tr>
- <%
- }
- }
- }
- %>
- </table>
- <h2>Table Schema</h2>
- <table class="table table-striped">
- <%
- ColumnFamilyDescriptor[] families =
table.getDescriptor().getColumnFamilies();
- Set<Bytes> familyKeySet = new HashSet<>();
- for (ColumnFamilyDescriptor family: families) {
- familyKeySet.addAll(family.getValues().keySet());
+ } else {
+ masterSnapshot =
master.getQuotaObserverChore().getTableQuotaSnapshots().get(tn);
+ }
+ if (quota != null && quota.hasSpace()) {
+ SpaceQuota spaceQuota = quota.getSpace();
+%>
+ <tr>
+ <td>Space Quota</td>
+ <td>
+ <table>
+ <tr>
+ <th>Property</th>
+ <th>Value</th>
+ </tr>
+ <tr>
+ <td>Limit</td>
+ <td><%= StringUtils.byteDesc(spaceQuota.getSoftLimit()) %></td>
+ </tr>
+ <tr>
+ <td>Policy</td>
+ <td><%= spaceQuota.getViolationPolicy() %></td>
+ </tr>
+<%
+ if (masterSnapshot != null) {
+%>
+ <tr>
+ <td>Usage</td>
+ <td><%= StringUtils.byteDesc(masterSnapshot.getUsage()) %></td>
+ </tr>
+ <tr>
+ <td>State</td>
+ <td><%= masterSnapshot.getQuotaStatus().isInViolation() ? "In
Violation" : "In Observance" %></td>
+ </tr>
+<%
}
+%>
+ </table>
+ </td>
+ <td>Information about a Space Quota on this table, if set.</td>
+ </tr>
+<%
+ }
+ if (quota != null && quota.hasThrottle()) {
+ List<ThrottleSettings> throttles =
QuotaSettingsFactory.fromTableThrottles(table.getName(), quota.getThrottle());
+ if (throttles.size() > 0) {
+%>
+ <tr>
+ <td>Throttle Quota</td>
+ <td>
+ <table>
+ <tr>
+ <th>Limit</th>
+ <th>Type</th>
+ <th>TimeUnit</th>
+ <th>Scope</th>
+ </tr>
+<%
+ for (ThrottleSettings throttle : throttles) {
+%>
+ <tr>
+ <td><%= throttle.getSoftLimit() %></td>
+ <td><%= throttle.getThrottleType() %></td>
+ <td><%= throttle.getTimeUnit() %></td>
+ <td><%= throttle.getQuotaScope() %></td>
+ </tr>
+<%
+ }
+%>
+ </table>
+ </td>
+ <td>Information about a Throttle Quota on this table, if set.</td>
+ </tr>
+<%
+ }
+ }
+ }
+%>
+</table>
+<h2>Table Schema</h2>
+<table class="table table-striped">
+<%
+ ColumnFamilyDescriptor[] families =
table.getDescriptor().getColumnFamilies();
+ Set<Bytes> familyKeySet = new HashSet<>();
+ for (ColumnFamilyDescriptor family: families) {
+ familyKeySet.addAll(family.getValues().keySet());
+ }
+%>
+ <tr>
+ <th>Property \ Column Family Name</th>
+ <%
+ for (ColumnFamilyDescriptor family: families) {
+ %>
+ <th>
+ <%= StringEscapeUtils.escapeHtml4(family.getNameAsString()) %>
+ </th>
+ <% } %>
+ </tr>
+ <%
+ for (Bytes familyKey: familyKeySet) {
%>
<tr>
- <th>Property \ Column Family Name</th>
+ <td>
+ <%= StringEscapeUtils.escapeHtml4(familyKey.toString()) %>
+ </td>
<%
for (ColumnFamilyDescriptor family: families) {
- %>
- <th>
- <%= StringEscapeUtils.escapeHtml4(family.getNameAsString()) %>
- </th>
- <% } %>
- </tr>
- <%
- for (Bytes familyKey: familyKeySet) {
- %>
- <tr>
- <td>
- <%= StringEscapeUtils.escapeHtml4(familyKey.toString()) %>
- </td>
- <%
- for (ColumnFamilyDescriptor family: families) {
- String familyValue = "-";
- if(family.getValues().containsKey(familyKey)){
- familyValue = family.getValues().get(familyKey).toString();
- }
- %>
- <td>
- <%= StringEscapeUtils.escapeHtml4(familyValue) %>
- </td>
- <% } %>
- </tr>
- <% } %>
- </table>
- <%
- long totalReadReq = 0;
- long totalWriteReq = 0;
- long totalSize = 0;
- long totalStoreFileCount = 0;
- long totalMemSize = 0;
- long totalCompactingCells = 0;
- long totalCompactedCells = 0;
- long totalBlocksTotalWeight = 0;
- long totalBlocksLocalWeight = 0;
- long totalBlocksLocalWithSsdWeight = 0;
- String totalCompactionProgress = "";
- String totalMemSizeStr = ZEROMB;
- String totalSizeStr = ZEROMB;
- String totalLocality = "";
- String totalLocalityForSsd = "";
- String urlRegionServer = null;
- Map<ServerName, Integer> regDistribution = new TreeMap<>();
- Map<ServerName, Integer> primaryRegDistribution = new TreeMap<>();
- List<HRegionLocation> regions = r.getAllRegionLocations();
- Map<RegionInfo, RegionMetrics> regionsToLoad = new LinkedHashMap<>();
- Map<RegionInfo, ServerName> regionsToServer = new LinkedHashMap<>();
- for (HRegionLocation hriEntry : regions) {
- RegionInfo regionInfo = hriEntry.getRegionInfo();
- ServerName addr = hriEntry.getServerName();
- regionsToServer.put(regionInfo, addr);
-
- if (addr != null) {
- ServerMetrics sl = master.getServerManager().getLoad(addr);
- if (sl != null) {
- RegionMetrics regionMetrics =
sl.getRegionMetrics().get(regionInfo.getRegionName());
- regionsToLoad.put(regionInfo, regionMetrics);
- if (regionMetrics != null) {
- totalReadReq += regionMetrics.getReadRequestCount();
- totalWriteReq += regionMetrics.getWriteRequestCount();
- totalSize +=
regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE);
- totalStoreFileCount += regionMetrics.getStoreFileCount();
- totalMemSize +=
regionMetrics.getMemStoreSize().get(Size.Unit.MEGABYTE);
- totalStoreFileSizeMB +=
regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE);
- totalCompactingCells += regionMetrics.getCompactingCellCount();
- totalCompactedCells += regionMetrics.getCompactedCellCount();
- totalBlocksTotalWeight += regionMetrics.getBlocksTotalWeight();
- totalBlocksLocalWeight += regionMetrics.getBlocksLocalWeight();
- totalBlocksLocalWithSsdWeight +=
regionMetrics.getBlocksLocalWithSsdWeight();
- } else {
- RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
- regionsToLoad.put(regionInfo, load0);
+ String familyValue = "-";
+ if(family.getValues().containsKey(familyKey)){
+ familyValue = family.getValues().get(familyKey).toString();
}
- } else{
- RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
- regionsToLoad.put(regionInfo, load0);
- }
+ %>
+ <td>
+ <%= StringEscapeUtils.escapeHtml4(familyValue) %>
+ </td>
+ <% } %>
+ </tr>
+ <% } %>
+</table>
+<%
+ long totalReadReq = 0;
+ long totalWriteReq = 0;
+ long totalSizeUncompressed = 0;
+ long totalSize = 0;
+ long totalStoreFileCount = 0;
+ long totalMemSize = 0;
+ long totalCompactingCells = 0;
+ long totalCompactedCells = 0;
+ long totalBlocksTotalWeight = 0;
+ long totalBlocksLocalWeight = 0;
+ long totalBlocksLocalWithSsdWeight = 0;
+ String totalCompactionProgress = "";
+ String totalMemSizeStr = ZEROMB;
+ String totalSizeUncompressedStr = ZEROMB;
+ String totalSizeStr = ZEROMB;
+ String totalLocality = "";
+ String totalLocalityForSsd = "";
+ String urlRegionServer = null;
+ Map<ServerName, Integer> regDistribution = new TreeMap<>();
+ Map<ServerName, Integer> primaryRegDistribution = new TreeMap<>();
+ List<HRegionLocation> regions = r.getAllRegionLocations();
+ Map<RegionInfo, RegionMetrics> regionsToLoad = new LinkedHashMap<>();
+ Map<RegionInfo, ServerName> regionsToServer = new LinkedHashMap<>();
+ for (HRegionLocation hriEntry : regions) {
+ RegionInfo regionInfo = hriEntry.getRegionInfo();
+ ServerName addr = hriEntry.getServerName();
+ regionsToServer.put(regionInfo, addr);
+
+ if (addr != null) {
+ ServerMetrics sl = master.getServerManager().getLoad(addr);
+ if (sl != null) {
+ RegionMetrics regionMetrics =
sl.getRegionMetrics().get(regionInfo.getRegionName());
+ regionsToLoad.put(regionInfo, regionMetrics);
+ if (regionMetrics != null) {
+ totalReadReq += regionMetrics.getReadRequestCount();
+ totalWriteReq += regionMetrics.getWriteRequestCount();
+ totalSizeUncompressed +=
regionMetrics.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE);
+ totalSize +=
regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE);
+ totalStoreFileCount += regionMetrics.getStoreFileCount();
+ totalMemSize +=
regionMetrics.getMemStoreSize().get(Size.Unit.MEGABYTE);
+ totalStoreFileSizeMB +=
regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE);
+ totalCompactingCells += regionMetrics.getCompactingCellCount();
+ totalCompactedCells += regionMetrics.getCompactedCellCount();
+ totalBlocksTotalWeight += regionMetrics.getBlocksTotalWeight();
+ totalBlocksLocalWeight += regionMetrics.getBlocksLocalWeight();
+ totalBlocksLocalWithSsdWeight +=
regionMetrics.getBlocksLocalWithSsdWeight();
} else {
RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
regionsToLoad.put(regionInfo, load0);
}
+ } else{
+ RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
+ regionsToLoad.put(regionInfo, load0);
}
- if (totalSize > 0) {
- totalSizeStr = StringUtils.byteDesc(totalSize*1024l*1024);
- }
- if (totalMemSize > 0) {
- totalMemSizeStr = StringUtils.byteDesc(totalMemSize*1024l*1024);
- }
- if (totalCompactingCells > 0) {
- totalCompactionProgress = String.format("%.2f", 100 *
- ((float) totalCompactedCells / totalCompactingCells)) + "%";
- }
- if (totalBlocksTotalWeight > 0) {
- totalLocality = String.format("%.1f",
- ((float) totalBlocksLocalWeight / totalBlocksTotalWeight));
- totalLocalityForSsd = String.format("%.1f",
- ((float) totalBlocksLocalWithSsdWeight / totalBlocksTotalWeight));
- }
- if(regions != null && regions.size() > 0) { %>
- <h2>Table Regions</h2>
- <div class="tabbable">
- <ul class="nav nav-pills">
- <li class="active">
- <a href="#tab_baseStats" data-toggle="tab">Base Stats</a>
- </li>
- <li class="">
- <a href="#tab_localityStats" data-toggle="tab">Localities</a>
- </li>
- <li class="">
- <a href="#tab_compactStats" data-toggle="tab">Compactions</a>
- </li>
- </ul>
- <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px
solid #ddd;">
- <div class="tab-pane active" id="tab_baseStats">
- <table id="regionServerDetailsTable" class="tablesorter table
table-striped">
- <thead>
- <tr>
- <th>Name(<%= String.format("%,1d", regions.size())%>)</th>
- <th>Region Server</th>
- <th>ReadRequests<br>(<%= String.format("%,1d",
totalReadReq)%>)</th>
- <th>WriteRequests<br>(<%= String.format("%,1d",
totalWriteReq)%>)</th>
- <th>StorefileSize<br>(<%= totalSizeStr %>)</th>
- <th>Num.Storefiles<br>(<%= String.format("%,1d",
totalStoreFileCount)%>)</th>
- <th>MemSize<br>(<%= totalMemSizeStr %>)</th>
- <th>Start Key</th>
- <th>End Key</th>
- <th>Region State</th>
- <%
- if (withReplica) {
- %>
- <th>ReplicaID</th>
- <%
- }
- %>
- </tr>
- </thead>
- <tbody>
- <%
- List<Map.Entry<RegionInfo, RegionMetrics>> entryList = new
ArrayList<>(regionsToLoad.entrySet());
- numRegions = regions.size();
- int numRegionsRendered = 0;
- // render all regions
- if (numRegionsToRender < 0) {
- numRegionsToRender = numRegions;
+ } else {
+ RegionMetrics load0 = getEmptyRegionMetrics(regionInfo);
+ regionsToLoad.put(regionInfo, load0);
+ }
+ }
+ if (totalSize > 0) {
+ totalSizeStr = StringUtils.byteDesc(totalSize*1024l*1024);
+ }
+ if (totalSizeUncompressed > 0){
+ totalSizeUncompressedStr =
StringUtils.byteDesc(totalSizeUncompressed*1024l*1024);
+ }
+ if (totalMemSize > 0) {
+ totalMemSizeStr = StringUtils.byteDesc(totalMemSize*1024l*1024);
+ }
+ if (totalCompactingCells > 0) {
+ totalCompactionProgress = String.format("%.2f", 100 *
+ ((float) totalCompactedCells / totalCompactingCells)) + "%";
+ }
+ if (totalBlocksTotalWeight > 0) {
+ totalLocality = String.format("%.1f",
+ ((float) totalBlocksLocalWeight / totalBlocksTotalWeight));
+ totalLocalityForSsd = String.format("%.1f",
+ ((float) totalBlocksLocalWithSsdWeight / totalBlocksTotalWeight));
+ }
+ if(regions != null && regions.size() > 0) { %>
+<h2>Table Regions</h2>
+<div class="tabbable">
+ <ul class="nav nav-pills">
+ <li class="active"><a href="#tab_baseStats" data-toggle="tab">Base
Stats</a></li>
+ <li class=""><a href="#tab_localityStats"
data-toggle="tab">Localities</a></li>
+ <li class=""><a href="#tab_compactStats"
data-toggle="tab">Compactions</a></li>
+ </ul>
+ <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px
solid #ddd;">
+ <div class="tab-pane active" id="tab_baseStats">
+ <table id="tableBaseStatsTable" class="tablesorter table table-striped">
+ <thead>
+ <tr>
+ <th>Name(<%= String.format("%,1d", regions.size())%>)</th>
+ <th>Region Server</th>
+ <th>ReadRequests<br>(<%= String.format("%,1d",
totalReadReq)%>)</th>
+ <th>WriteRequests<br>(<%= String.format("%,1d",
totalWriteReq)%>)</th>
+ <th>Uncompressed StoreFileSize<br>(<%= totalSizeUncompressedStr
%>)</th>
+ <th>StorefileSize<br>(<%= totalSizeStr %>)</th>
+ <th>Num.Storefiles<br>(<%= String.format("%,1d",
totalStoreFileCount)%>)</th>
+ <th>MemSize<br>(<%= totalMemSizeStr %>)</th>
+ <th>Start Key</th>
+ <th>End Key</th>
+ <th>Region State</th>
+ <th>ReplicaID</th>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ List<Map.Entry<RegionInfo, RegionMetrics>> entryList = new
ArrayList<>(regionsToLoad.entrySet());
+ numRegions = regions.size();
+ int numRegionsRendered = 0;
+ // render all regions
+ if (numRegionsToRender < 0) {
+ numRegionsToRender = numRegions;
+ }
+ for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
+ RegionInfo regionInfo = hriEntry.getKey();
+ ServerName addr = regionsToServer.get(regionInfo);
+ RegionMetrics load = hriEntry.getValue();
+ String readReq = "N/A";
+ String writeReq = "N/A";
+ String regionSizeUncompressed = ZEROMB;
+ String regionSize = ZEROMB;
+ String fileCount = "N/A";
+ String memSize = ZEROMB;
+ String state = "N/A";
+ if (load != null) {
+ readReq = String.format("%,1d", load.getReadRequestCount());
+ writeReq = String.format("%,1d", load.getWriteRequestCount());
+ double rSizeUncompressed =
load.getUncompressedStoreFileSize().get(Size.Unit.BYTE);
+ if (rSizeUncompressed > 0) {
+ regionSizeUncompressed =
StringUtils.byteDesc((long)rSizeUncompressed);
}
- for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
- RegionInfo regionInfo = hriEntry.getKey();
- ServerName addr = regionsToServer.get(regionInfo);
- RegionMetrics load = hriEntry.getValue();
- String readReq = "N/A";
- String writeReq = "N/A";
- String regionSize = ZEROMB;
- String fileCount = "N/A";
- String memSize = ZEROMB;
- String state = "N/A";
- if (load != null) {
- readReq = String.format("%,1d", load.getReadRequestCount());
- writeReq = String.format("%,1d",
load.getWriteRequestCount());
- double rSize = load.getStoreFileSize().get(Size.Unit.BYTE);
- if (rSize > 0) {
- regionSize = StringUtils.byteDesc((long)rSize);
- }
- fileCount = String.format("%,1d", load.getStoreFileCount());
- double mSize = load.getMemStoreSize().get(Size.Unit.BYTE);
- if (mSize > 0) {
- memSize = StringUtils.byteDesc((long)mSize);
- }
- }
- if (stateMap.containsKey(regionInfo.getEncodedName())) {
- state = stateMap.get(regionInfo.getEncodedName()).toString();
- }
- if (addr != null) {
- ServerMetrics sl = master.getServerManager().getLoad(addr);
- // This port might be wrong if RS actually ended up using
something else.
- urlRegionServer =
- "//" + URLEncoder.encode(addr.getHostname()) + ":" +
master.getRegionServerInfoPort(addr) + "/rs-status";
- if(sl != null) {
- Integer i = regDistribution.get(addr);
- if (null == i) i = Integer.valueOf(0);
- regDistribution.put(addr, i + 1);
- if (withReplica &&
RegionReplicaUtil.isDefaultReplica(regionInfo.getReplicaId())) {
- i = primaryRegDistribution.get(addr);
- if (null == i) i = Integer.valueOf(0);
- primaryRegDistribution.put(addr, i+1);
- }
- }
- }
- if (numRegionsRendered < numRegionsToRender) {
- numRegionsRendered++;
- %>
- <tr>
- <td><%=
escapeXml(Bytes.toStringBinary(regionInfo.getRegionName())) %></td>
- <%
- if (urlRegionServer != null) {
- %>
- <td>
- <a href="<%= urlRegionServer %>"><%= addr == null? "-":
StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" +
master.getRegionServerInfoPort(addr) %></a>
- </td>
- <%
- } else {
- %>
- <td class="undeployed-region">not deployed</td>
- <%
- }
- %>
- <td><%= readReq%></td>
- <td><%= writeReq%></td>
- <td><%= regionSize%></td>
- <td><%= fileCount%></td>
- <td><%= memSize%></td>
- <td><%=
escapeXml(Bytes.toStringBinary(regionInfo.getStartKey()))%></td>
- <td><%=
escapeXml(Bytes.toStringBinary(regionInfo.getEndKey()))%></td>
- <td><%= state%></td>
- <%
- if (withReplica) {
- %>
- <td><%= regionInfo.getReplicaId() %></td>
- <%
- }
- %>
- </tr>
- <% } %>
- <% } %>
- </tbody>
- </table>
- <% if (numRegions > numRegionsRendered) {
- String allRegionsUrl = "?name=" + URLEncoder.encode(fqtn,"UTF-8")
+ "&numRegions=all";
- %>
- <p>This table has <b><%= numRegions %></b> regions in total, in
order to improve the page load time,
- only <b><%= numRegionsRendered %></b> regions are displayed here,
<a href="<%= allRegionsUrl %>">click
- here</a> to see all regions.</p>
- <% } %>
- </div>
- <div class="tab-pane" id="tab_localityStats">
- <table id="regionServerDetailsTable" class="tablesorter table
table-striped">
- <thead>
- <tr>
- <th>Name(<%= String.format("%,1d", regions.size())%>)</th>
- <th>Region Server</th>
- <th>Locality<br>(<%= totalLocality %>)</th>
- <th>LocalityForSsd<br>(<%= totalLocalityForSsd %>)</th>
- </tr>
- </thead>
- <tbody>
- <%
- numRegionsRendered = 0;
- for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
- RegionInfo regionInfo = hriEntry.getKey();
- ServerName addr = regionsToServer.get(regionInfo);
- RegionMetrics load = hriEntry.getValue();
- float locality = 0.0f;
- float localityForSsd = 0.0f;
- String state = "N/A";
- if (load != null) {
- locality = load.getDataLocality();
- localityForSsd = load.getDataLocalityForSsd();
- }
- if (addr != null) {
- // This port might be wrong if RS actually ended up using
something else.
- urlRegionServer =
- "//" + URLEncoder.encode(addr.getHostname()) + ":" +
master.getRegionServerInfoPort(addr) + "/rs-status";
- }
- if (numRegionsRendered < numRegionsToRender) {
- numRegionsRendered++;
- %>
- <tr>
- <td><%=
escapeXml(Bytes.toStringBinary(regionInfo.getRegionName())) %></td>
- <%
- if (urlRegionServer != null) {
- %>
- <td>
- <a href="<%= urlRegionServer %>"><%= addr == null? "-":
StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" +
master.getRegionServerInfoPort(addr) %></a>
- </td>
- <%
- } else {
- %>
- <td class="undeployed-region">not deployed</td>
- <%
+ double rSize = load.getStoreFileSize().get(Size.Unit.BYTE);
+ if (rSize > 0) {
+ regionSize = StringUtils.byteDesc((long)rSize);
}
- %>
- <td><%= locality%></td>
- <td><%= localityForSsd%></td>
- </tr>
- <% } %>
- <% } %>
- </tbody>
- </table>
- </div>
- <div class="tab-pane" id="tab_compactStats">
- <table id="tableCompactStatsTable" class="tablesorter table
table-striped">
- <thead>
- <tr>
- <th>Name(<%= String.format("%,1d", regions.size())%>)</th>
- <th>Region Server</th>
- <th>Num. Compacting Cells<br>(<%= String.format("%,1d",
totalCompactingCells)%>)</th>
- <th>Num. Compacted Cells<br>(<%= String.format("%,1d",
totalCompactedCells)%>)</th>
- <th>Remaining Cells<br>(<%= String.format("%,1d",
totalCompactingCells-totalCompactedCells)%>)</th>
- <th>Compaction Progress<br>(<%= totalCompactionProgress %>)</th>
- </tr>
- </thead>
- <tbody>
- <%
- numRegionsRendered = 0;
- for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
- RegionInfo regionInfo = hriEntry.getKey();
- ServerName addr = regionsToServer.get(regionInfo);
- RegionMetrics load = hriEntry.getValue();
- long compactingCells = 0;
- long compactedCells = 0;
- String compactionProgress = "";
- if (load != null) {
- compactingCells = load.getCompactingCellCount();
- compactedCells = load.getCompactedCellCount();
- if (compactingCells > 0) {
- compactionProgress = String.format("%.2f", 100 * ((float)
- compactedCells / compactingCells)) + "%";
- }
- }
- if (addr != null) {
- // This port might be wrong if RS actually ended up using
something else.
- urlRegionServer =
- "//" + URLEncoder.encode(addr.getHostname()) + ":" +
master.getRegionServerInfoPort(addr) + "/rs-status";
- }
- if (numRegionsRendered < numRegionsToRender) {
- numRegionsRendered++;
- %>
- <tr>
- <td><%=
escapeXml(Bytes.toStringBinary(regionInfo.getRegionName())) %></td>
- <%
- if (urlRegionServer != null) {
- %>
- <td>
- <a href="<%= urlRegionServer %>"><%= addr == null? "-":
StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" +
master.getRegionServerInfoPort(addr) %></a>
- </td>
- <%
- } else {
- %>
- <td class="undeployed-region">not deployed</td>
- <%
+ fileCount = String.format("%,1d", load.getStoreFileCount());
+ double mSize = load.getMemStoreSize().get(Size.Unit.BYTE);
+ if (mSize > 0) {
+ memSize = StringUtils.byteDesc((long)mSize);
+ }
+ }
+
+ if (stateMap.containsKey(regionInfo.getEncodedName())) {
+ state = stateMap.get(regionInfo.getEncodedName()).toString();
+ }
+
+ if (addr != null) {
+ ServerMetrics sl = master.getServerManager().getLoad(addr);
+ if(sl != null) {
+ Integer i = regDistribution.get(addr);
+ if (null == i) i = Integer.valueOf(0);
+ regDistribution.put(addr, i + 1);
+ if
(RegionReplicaUtil.isDefaultReplica(regionInfo.getReplicaId())) {
+ i = primaryRegDistribution.get(addr);
+ if (null == i) i = Integer.valueOf(0);
+ primaryRegDistribution.put(addr, i+1);
}
- %>
- <td><%= String.format("%,1d", compactingCells)%></td>
- <td><%= String.format("%,1d", compactedCells)%></td>
- <td><%= String.format("%,1d", compactingCells -
compactedCells)%></td>
- <td><%= compactionProgress%></td>
- </tr>
- <% } %>
- <% } %>
- </tbody>
- </table>
- <% if (numRegions > numRegionsRendered) {
- String allRegionsUrl = "?name=" + URLEncoder.encode(fqtn,"UTF-8")
+ "&numRegions=all";
- %>
- <p>This table has <b><%= numRegions %></b> regions in total, in
order to improve the page load time,
- only <b><%= numRegionsRendered %></b> regions are displayed here,
<a href="<%= allRegionsUrl %>">click
- here</a> to see all regions.</p>
- <% } %>
- </div>
- </div>
+ }
+ }
+ if (numRegionsRendered < numRegionsToRender) {
+ numRegionsRendered++;
+ %>
+ <tr>
+ <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getRegionName()))
%></td>
+ <%= buildRegionDeployedServerTag(regionInfo, master,
regionsToServer) %>
+ <td><%= readReq%></td>
+ <td><%= writeReq%></td>
+ <td><%= regionSizeUncompressed%></td>
+ <td><%= regionSize%></td>
+ <td><%= fileCount%></td>
+ <td><%= memSize%></td>
+ <td><%=
escapeXml(Bytes.toStringBinary(regionInfo.getStartKey()))%></td>
+ <td><%=
escapeXml(Bytes.toStringBinary(regionInfo.getEndKey()))%></td>
+ <td><%= state%></td>
+ <td><%= regionInfo.getReplicaId() %></td>
+ </tr>
+ <% } %>
+ <% } %>
+ </tbody>
+ </table>
+ <%= moreRegionsToRender(numRegionsRendered, numRegions, fqtn) %>
</div>
- <h2>Regions by Region Server</h2>
- <%
- if (withReplica) {
- %>
- <table id="regionServerTable" class="tablesorter table
table-striped"><thead><tr><th>Region Server</th><th>Region
Count</th><th>Primary Region Count</th></tr></thead>
- <%
-} else {
-%>
- <table id="regionServerTable" class="tablesorter table
table-striped"><thead><tr><th>Region Server</th><th>Region
Count</th></tr></thead>
+ <div class="tab-pane" id="tab_localityStats">
+ <table id="tableLocalityStatsTable" class="tablesorter table
table-striped">
+ <thead>
+ <tr>
+ <th>Name(<%= String.format("%,1d", regions.size())%>)</th>
+ <th>Region Server</th>
+ <th>Locality<br>(<%= totalLocality %>)</th>
+ <th>LocalityForSsd<br>(<%= totalLocalityForSsd %>)</th>
+ </tr>
+ </thead>
<tbody>
<%
- }
+ numRegionsRendered = 0;
+ for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
+ RegionInfo regionInfo = hriEntry.getKey();
+ ServerName addr = regionsToServer.get(regionInfo);
+ RegionMetrics load = hriEntry.getValue();
+ float locality = 0.0f;
+ float localityForSsd = 0.0f;
+ String state = "N/A";
+ if (load != null) {
+ locality = load.getDataLocality();
+ localityForSsd = load.getDataLocalityForSsd();
+ }
+
+ if (numRegionsRendered < numRegionsToRender) {
+ numRegionsRendered++;
%>
+ <tr>
+ <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getRegionName()))
%></td>
+ <%= buildRegionDeployedServerTag(regionInfo, master,
regionsToServer) %>
+ <td><%= locality%></td>
+ <td><%= localityForSsd%></td>
+ </tr>
+ <% } %>
+ <% } %>
+ </tbody>
+ </table>
+ <%= moreRegionsToRender(numRegionsRendered, numRegions, fqtn) %>
+ </div>
+ <div class="tab-pane" id="tab_compactStats">
+ <table id="tableCompactStatsTable" class="tablesorter table
table-striped">
+ <thead>
+ <tr>
+ <th>Name(<%= String.format("%,1d", regions.size())%>)</th>
+ <th>Region Server</th>
+ <th>Num. Compacting Cells<br>(<%= String.format("%,1d",
totalCompactingCells)%>)</th>
+ <th>Num. Compacted Cells<br>(<%= String.format("%,1d",
totalCompactedCells)%>)</th>
+ <th>Remaining Cells<br>(<%= String.format("%,1d",
totalCompactingCells-totalCompactedCells)%>)</th>
+ <th>Compaction Progress<br>(<%= totalCompactionProgress %>)</th>
+ </tr>
+ </thead>
+ <tbody>
<%
- for (Map.Entry<ServerName, Integer> rdEntry :
regDistribution.entrySet()) {
- ServerName addr = rdEntry.getKey();
- String url = "//" + URLEncoder.encode(addr.getHostname()) + ":" +
master.getRegionServerInfoPort(addr) + "/rs-status";
+ numRegionsRendered = 0;
+ for (Map.Entry<RegionInfo, RegionMetrics> hriEntry : entryList) {
+ RegionInfo regionInfo = hriEntry.getKey();
+ ServerName addr = regionsToServer.get(regionInfo);
+ RegionMetrics load = hriEntry.getValue();
+ long compactingCells = 0;
+ long compactedCells = 0;
+ String compactionProgress = "";
+ if (load != null) {
+ compactingCells = load.getCompactingCellCount();
+ compactedCells = load.getCompactedCellCount();
+ if (compactingCells > 0) {
+ compactionProgress = String.format("%.2f", 100 * ((float)
+ compactedCells / compactingCells)) + "%";
+ }
+ }
+
+ if (numRegionsRendered < numRegionsToRender) {
+ numRegionsRendered++;
%>
<tr>
- <td><a href="<%= url %>"><%=
StringEscapeUtils.escapeHtml4(addr.getHostname().toString()) + ":" +
master.getRegionServerInfoPort(addr) %></a></td>
- <td><%= rdEntry.getValue()%></td>
- <%
- if (withReplica) {
- %>
- <td><%= primaryRegDistribution.get(addr)%></td>
- <%
- }
- %>
+ <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getRegionName()))
%></td>
+ <%= buildRegionDeployedServerTag(regionInfo, master,
regionsToServer) %>
+ <td><%= String.format("%,1d", compactingCells)%></td>
+ <td><%= String.format("%,1d", compactedCells)%></td>
+ <td><%= String.format("%,1d", compactingCells -
compactedCells)%></td>
+ <td><%= compactionProgress%></td>
</tr>
<% } %>
+ <% } %>
</tbody>
</table>
- <% }
+ <%= moreRegionsToRender(numRegionsRendered, numRegions, fqtn) %>
+ </div>
+ </div>
+</div>
+
+<h2>Regions by Region Server</h2>
+<table id="regionServerTable" class="tablesorter table table-striped">
+ <thead>
+ <tr>
+ <th>Region Server</th><th>Region Count</th><th>Primary Region Count</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <%
+ for (Map.Entry<ServerName, Integer> rdEntry : regDistribution.entrySet()) {
+ ServerName addr = rdEntry.getKey();
+ String url = "//" + URLEncoder.encode(addr.getHostname()) + ":"
+ + master.getRegionServerInfoPort(addr) + "/rs-status";
+ %>
+ <tr>
+ <td><a href="<%= url %>"><%=
StringEscapeUtils.escapeHtml4(addr.getHostname().toString())
+ + ":" + master.getRegionServerInfoPort(addr) %></a></td>
+ <td><%= rdEntry.getValue()%></td>
+ <td><%= primaryRegDistribution.get(addr) == null ? 0 :
primaryRegDistribution.get(addr)%></td>
+ </tr>
+ <% } %>
+ </tbody>
+</table>
+
+<% }
} catch(Exception ex) { %>
Unknown Issue with Regions
<div
onclick="document.getElementById('closeStackTrace').style.display='block';document.getElementById('openStackTrace').style.display='none';">
@@ -1182,105 +1183,87 @@
</tr>
</table>
- <% if (!readOnly) { %>
- <p><hr/></p>
- Actions:
- <p>
- <center>
- <table class="table" style="border: 0;" width="95%" >
- <tr>
- <form method="get">
- <input type="hidden" name="action" value="compact" />
- <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
- <td class="centered">
- <input style="font-size: 12pt; width: 10em" type="submit"
value="Compact" class="btn" />
- </td>
- <td style="text-align: center;">
- <input type="text" name="key" size="40" placeholder="Row Key
(optional)" />
- </td>
- <td>
- This action will force a compaction of all regions of the
table, or,
- if a key is supplied, only the region containing the
- given key.
- </td>
- </form>
- </tr>
- <tr>
- <form method="get">
- <input type="hidden" name="action" value="split" />
- <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
- <td class="centered">
- <input style="font-size: 12pt; width: 10em" type="submit"
value="Split" class="btn" />
- </td>
- <td style="text-align: center;">
- <input type="text" name="key" size="40" placeholder="Row Key
(optional)" />
- </td>
- <td>
- This action will force a split of all eligible
- regions of the table, or, if a key is supplied, only the
region containing the
- given key. An eligible region is one that does not contain any
references to
- other regions. Split requests for noneligible regions will be
ignored.
- </td>
- </form>
- </tr>
- <tr>
- <form method="get">
- <input type="hidden" name="action" value="merge" />
- <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
- <td class="centered">
- <input style="font-size: 12pt; width: 10em" type="submit"
value="Merge" class="btn" />
- </td>
- <td style="text-align: center;">
- <input type="text" name="left" size="40" placeholder="Region
Key (required)" />
- <input type="text" name="right" size="40" placeholder="Region
Key (required)" />
- </td>
- <td>
- This action will merge two regions of the table, Merge
requests for
- noneligible regions will be ignored.
- </td>
- </form>
- </tr>
- </table>
- </center>
- </p>
- <% } %>
- </div>
+<% if (!readOnly) { %>
+<p><hr/></p>
+Actions:
+<p>
+<center>
+<table class="table" style="border: 0;" width="95%" >
+<tr>
+ <form method="get">
+ <input type="hidden" name="action" value="major compact" />
+ <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
+ <td class="centered">
+ <input style="font-size: 12pt; width: 10em" type="submit" value="Major
Compact" class="btn" />
+ </td>
+ <td style="text-align: center;">
+ <input type="text" name="key" size="40" placeholder="Row Key (optional)" />
+ </td>
+ <td>
+ This action will force a major compaction of all regions of the table, or,
+ if a key is supplied, only the region major containing the
+ given key.
+ </td>
+ </form>
+</tr>
+<tr>
+ <form method="get">
+ <input type="hidden" name="action" value="compact" />
+ <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
+ <td class="centered">
+ <input style="font-size: 12pt; width: 10em" type="submit" value="Compact"
class="btn" />
+ </td>
+ <td style="text-align: center;">
+ <input type="text" name="key" size="40" placeholder="Row Key (optional)" />
+ </td>
+ <td>
+ This action will force a compaction of all regions of the table, or,
+ if a key is supplied, only the region containing the
+ given key.
+ </td>
+ </form>
+</tr>
+<tr>
+ <form method="get">
+ <input type="hidden" name="action" value="split" />
+ <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
+ <td class="centered">
+ <input style="font-size: 12pt; width: 10em" type="submit" value="Split"
class="btn" />
+ </td>
+ <td style="text-align: center;">
+ <input type="text" name="key" size="40" placeholder="Row Key (optional)" />
+ </td>
+ <td>
+ This action will force a split of all eligible
+ regions of the table, or, if a key is supplied, only the region
containing the
+ given key. An eligible region is one that does not contain any
references to
+ other regions. Split requests for noneligible regions will be ignored.
+ </td>
+ </form>
+</tr>
+<tr>
+ <form method="get">
+ <input type="hidden" name="action" value="merge" />
+ <input type="hidden" name="name" value="<%= escaped_fqtn %>" />
+ <td class="centered">
+ <input style="font-size: 12pt; width: 10em" type="submit" value="Merge"
class="btn" />
+ </td>
+ <td style="text-align: center;">
+ <input type="text" name="left" size="40" required="required"
placeholder="Region Key (required)" />
+ <input type="text" name="right" size="40" required="required"
placeholder="Region Key (required)" />
+ </td>
+ <td>
+ This action will merge two regions of the table, Merge requests for
+ noneligible regions will be ignored.
+ </td>
+ </form>
+</tr>
+</table>
+</center>
+</p>
+<% } %>
</div>
-<% }
-} catch(TableNotFoundException e) { %>
-<div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table not found</h1>
- </div>
- </div>
- <p><hr><p>
- <p>Go <a href="javascript:history.back()">Back</a>
-</div> <%
-} catch(IllegalArgumentException e) { %>
-<div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table qualifier must not be empty</h1>
- </div>
- </div>
- <p><hr><p>
- <p>Go <a href="javascript:history.back()">Back</a>
-</div> <%
- }
-}
-else { // handle the case for fqtn is null or master is not initialized with
error message + redirect
-%>
-<div class="container-fluid content">
- <div class="row inner_header">
- <div class="page-header">
- <h1>Table not ready</h1>
- </div>
- </div>
- <p><hr><p>
- <jsp:include page="redirect.jsp" />
</div>
-<% } %>
<jsp:include page="footer.jsp" />
<script src="/static/js/jquery.min.js" type="text/javascript"></script>
@@ -1288,78 +1271,94 @@ else { // handle the case for fqtn is null or master is
not initialized with err
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script>
- $(document).ready(function()
+$(document).ready(function()
+ {
+ $.tablesorter.addParser(
{
- $.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( /(B|KB|MB|GB|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"
- });
- $("#regionServerTable").tablesorter({
- headers: {
- 1: {sorter: 'separator'}
- }
- });
- $("#regionServerDetailsTable").tablesorter({
- headers: {
- 2: {sorter: 'separator'},
- 3: {sorter: 'separator'},
- 4: {sorter: 'filesize'},
- 5: {sorter: 'separator'},
- 6: {sorter: 'filesize'}
- }
- });
- $("#tableRegionTable").tablesorter({
- headers: {
- 2: {sorter: 'separator'},
- 3: {sorter: 'separator'},
- 4: {sorter: 'filesize'},
- 5: {sorter: 'separator'},
- 6: {sorter: 'filesize'}
- }
- });
- $("#tableCompactStatsTable").tablesorter({
- headers: {
- 2: {sorter: 'separator'},
- 3: {sorter: 'separator'},
- 4: {sorter: 'separator'}
+ 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( /(B|KB|MB|GB|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;
}
- });
- $("#metaTableCompactStatsTable").tablesorter({
- headers: {
- 2: {sorter: 'separator'},
- 3: {sorter: 'separator'},
- 4: {sorter: 'separator'}
- }
- });
- }
- );
+ },
+ 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"
+ });
+ $("#regionServerTable").tablesorter({
+ headers: {
+ 1: {sorter: 'separator'}
+ }
+ });
+ $("#tableBaseStatsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'},
+ 4: {sorter: 'filesize'},
+ 5: {sorter: 'separator'},
+ 6: {sorter: 'filesize'},
+ 7: {empty: 'emptyMin'},
+ 8: {empty: 'emptyMax'}
+ }
+ });
+ $("#metaTableBaseStatsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'},
+ 4: {sorter: 'filesize'},
+ 5: {sorter: 'separator'},
+ 6: {sorter: 'filesize'},
+ 7: {empty: 'emptyMin'},
+ 8: {empty: 'emptyMax'}
+ }
+ });
+ $("#tableLocalityStatsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'}
+ }
+ });
+ $("#metaTableLocalityStatsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'}
+ }
+ });
+ $("#tableCompactStatsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'},
+ 4: {sorter: 'separator'}
+ }
+ });
+ $("#metaTableCompactStatsTable").tablesorter({
+ headers: {
+ 2: {sorter: 'separator'},
+ 3: {sorter: 'separator'},
+ 4: {sorter: 'separator'}
+ }
+ });
+ }
+);
</script>
diff --git
a/hbase-server/src/main/resources/hbase-webapps/regionserver/header.jsp
b/hbase-server/src/main/resources/hbase-webapps/regionserver/header.jsp
index edbecc424c6..6a616780e3c 100644
--- a/hbase-server/src/main/resources/hbase-webapps/regionserver/header.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/regionserver/header.jsp
@@ -56,7 +56,15 @@
<li><a href="/rsOperationDetails.jsp">Operation Details</a></li>
<li><a href="/logLevel">Log Level</a></li>
<li><a href="/dump">Debug Dump</a></li>
- <li><a href="/jmx">Metrics Dump</a></li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#"
id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
+ Metrics <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu"
aria-labelledby="navbarDropdownMenuLink">
+ <li><a target="_blank" href="/jmx">JMX</a></li>
+ <li><a target="_blank" href="/jmx?description=true">JMX with
description</a></li>
+ </ul>
+ </li>
<li><a href="/prof">Profiler</a></li>
<% if (HBaseConfiguration.isShowConfInServlet()) { %>
<li><a href="/conf">HBase Configuration</a></li>
diff --git a/hbase-thrift/src/main/resources/hbase-webapps/thrift/footer.jsp
b/hbase-thrift/src/main/resources/hbase-webapps/thrift/footer.jsp
new file mode 100644
index 00000000000..53a7d0cdbdb
--- /dev/null
+++ b/hbase-thrift/src/main/resources/hbase-webapps/thrift/footer.jsp
@@ -0,0 +1,30 @@
+<%--
+/**
+* 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.
+*/
+--%>
+ <script src="/static/js/jquery.min.js" type="text/javascript"></script>
+ <script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="/static/js/tab.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('li.active').removeClass('active');
+ $('a[href="' + location.pathname +
'"]').closest('li').addClass('active');
+ });
+ </script>
+ </body>
+</html>
diff --git a/hbase-thrift/src/main/resources/hbase-webapps/thrift/header.jsp
b/hbase-thrift/src/main/resources/hbase-webapps/thrift/header.jsp
new file mode 100644
index 00000000000..92566c7e828
--- /dev/null
+++ b/hbase-thrift/src/main/resources/hbase-webapps/thrift/header.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="org.apache.hadoop.hbase.HBaseConfiguration"%>
+
+<!DOCTYPE html>
+<?xml version="1.0" encoding="UTF-8" ?>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title><%= request.getParameter("pageTitle")%></title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="">
+
+ <link href="/static/css/bootstrap.min.css" rel="stylesheet">
+ <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
+ <link href="/static/css/hbase.css" rel="stylesheet">
+</head>
+
+<body>
+<div class="navbar navbar-fixed-top navbar-default">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button"
+ class="navbar-toggle" data-toggle="collapse"
data-target=".navbar-collapse">
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="navbar-brand" href="/thrift.jsp">
+ <img src="/static/hbase_logo_small.png" alt="HBase Logo"/>
+ </a>
+ </div>
+ <div class="collapse navbar-collapse">
+ <ul class="nav navbar-nav">
+ <li class="active"><a href="/thrift.jsp">Home</a></li>
+ <li><a href="/logs/">Local logs</a></li>
+ <li><a href="/logLevel">Log Level</a></li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#"
id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
+ Metrics <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
+ <li><a target="_blank" href="/jmx">JMX</a></li>
+ <li><a target="_blank" href="/jmx?description=true">JMX with
description</a></li>
+ </ul>
+ </li>
+ <li><a href="/prof">Profiler</a></li>
+ <% if (HBaseConfiguration.isShowConfInServlet()) { %>
+ <li><a href="/conf">HBase Configuration</a></li>
+ <% } %>
+ </ul>
+ </div><!--/.nav-collapse -->
+ </div>
+</div>
diff --git a/hbase-thrift/src/main/resources/hbase-webapps/thrift/thrift.jsp
b/hbase-thrift/src/main/resources/hbase-webapps/thrift/thrift.jsp
index cb22007bea6..d148df1f2e2 100644
--- a/hbase-thrift/src/main/resources/hbase-webapps/thrift/thrift.jsp
+++ b/hbase-thrift/src/main/resources/hbase-webapps/thrift/thrift.jsp
@@ -19,7 +19,6 @@
--%>
<%@ page contentType="text/html;charset=UTF-8"
import="org.apache.hadoop.conf.Configuration"
- import="org.apache.hadoop.hbase.HBaseConfiguration"
import="org.apache.hadoop.hbase.util.VersionInfo"
import="java.util.Date"
%>
@@ -27,54 +26,25 @@
<%@ page import="org.apache.hadoop.hbase.util.JvmVersion" %>
<%
-Configuration conf =
(Configuration)getServletContext().getAttribute("hbase.conf");
-String serverType =
(String)getServletContext().getAttribute("hbase.thrift.server.type");
-long startcode = conf.getLong("startcode", System.currentTimeMillis());
-String listenPort = conf.get("hbase.regionserver.thrift.port", "9090");
-ImplType implType = ImplType.getServerImpl(conf);
-String framed = implType.isAlwaysFramed()
- ? "true" : conf.get("hbase.regionserver.thrift.framed", "false");
-String compact = conf.get("hbase.regionserver.thrift.compact", "false");
-%>
-<!DOCTYPE html>
-<?xml version="1.0" encoding="UTF-8" ?>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>HBase Thrift Server: <%= listenPort %></title>
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="description" content="">
+ Configuration conf =
(Configuration)getServletContext().getAttribute("hbase.conf");
+ String serverType =
(String)getServletContext().getAttribute("hbase.thrift.server.type");
+ long startcode = conf.getLong("startcode", System.currentTimeMillis());
+ String listenPort = conf.get("hbase.regionserver.thrift.port", "9090");
+ ImplType implType = ImplType.getServerImpl(conf);
+
+ String transport =
+ (implType.isAlwaysFramed() ||
+ conf.getBoolean("hbase.regionserver.thrift.framed", false)) ? "Framed" :
"Standard";
+ String protocol =
+ conf.getBoolean("hbase.regionserver.thrift.compact", false) ? "Compact" :
"Binary";
+ String qop = conf.get("hbase.thrift.security.qop", "None");
- <link href="/static/css/bootstrap.min.css" rel="stylesheet">
- <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
- <link href="/static/css/hbase.css" rel="stylesheet">
- </head>
+ pageContext.setAttribute("pageTitle", "HBase Thrift Server: " + listenPort);
+%>
- <body>
- <div class="navbar navbar-fixed-top navbar-default">
- <div class="container-fluid">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle"
data-toggle="collapse" data-target=".navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="/thrift.jsp"><img
src="/static/hbase_logo_small.png" alt="HBase Logo"/></a>
- </div>
- <div class="collapse navbar-collapse">
- <ul class="nav navbar-nav">
- <li class="active"><a href="/">Home</a></li>
- <li><a href="/logs/">Local logs</a></li>
- <li><a href="/logLevel">Log Level</a></li>
- <li><a href="/jmx">Metrics Dump</a></li>
- <li><a href="/prof">Profiler</a></li>
- <% if (HBaseConfiguration.isShowConfInServlet()) { %>
- <li><a href="/conf">HBase Configuration</a></li>
- <% } %>
- </ul>
- </div><!--/.nav-collapse -->
- </div>
- </div>
+<jsp:include page="header.jsp">
+ <jsp:param name="pageTitle" value="${pageTitle}"/>
+</jsp:include>
<div class="container-fluid content">
<div class="row inner_header">
@@ -118,31 +88,34 @@ String compact =
conf.get("hbase.regionserver.thrift.compact", "false");
<td>Thrift RPC engine implementation type chosen by this Thrift
server</td>
</tr>
<tr>
- <td>Compact Protocol</td>
- <td><%= compact %></td>
- <td>Thrift RPC engine uses compact protocol</td>
+ <td>Protocol</td>
+ <td><%= protocol %></td>
+ <td>Thrift RPC engine protocol type</td>
</tr>
<tr>
- <td>Framed Transport</td>
- <td><%= framed %></td>
- <td>Thrift RPC engine uses framed transport</td>
+ <td>Transport</td>
+ <td><%= transport %></td>
+ <td>Thrift RPC engine transport type</td>
</tr>
<tr>
<td>Thrift Server Type</td>
<td><%= serverType %></td>
<td>The type of this Thrift server</td>
</tr>
+ <tr>
+ <td>Quality of Protection</td>
+ <td><%= qop %></td>
+ <td>QOP Settings for SASL</td>
+ </tr>
</table>
</section>
</div>
<div class="row">
<section>
- <a href="http://hbase.apache.org/book.html#_thrift">Apache HBase
Reference Guide chapter on Thrift</a>
+ <a href="http://hbase.apache.org/book.html#_thrift">
+ Apache HBase Reference Guide chapter on Thrift</a>
</section>
</div>
</div>
-<script src="/static/js/jquery.min.js" type="text/javascript"></script>
-<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
-<script src="/static/js/tab.js" type="text/javascript"></script>
-</body>
-</html>
+
+<jsp:include page="footer.jsp" />