HBASE-7171 Initial web UI for region/memstore/storefiles details

Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/2430efc2
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/2430efc2
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/2430efc2

Branch: refs/heads/hbase-12439
Commit: 2430efc2b2f2ec43e6ae1f88b6ebcb04f4e116c4
Parents: b449b0f
Author: Mikhail Antonov <[email protected]>
Authored: Tue Dec 8 13:53:21 2015 -0800
Committer: Mikhail Antonov <[email protected]>
Committed: Tue Dec 8 13:53:21 2015 -0800

----------------------------------------------------------------------
 .../tmpl/regionserver/RegionListTmpl.jamon      |  27 ++--
 .../hbase-webapps/regionserver/region.jsp       | 130 +++++++++++++++++++
 .../hbase-webapps/regionserver/storeFile.jsp    | 115 ++++++++++++++++
 3 files changed, 262 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/2430efc2/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
 
b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
index 33cdf00..7740c53 100644
--- 
a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
+++ 
b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
@@ -95,8 +95,11 @@
 
         <%for HRegionInfo r: onlineRegions %>
         <tr>
-            <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
-                                        regionServer.getConfiguration()) 
%></td>
+            <%java>
+             String displayName = 
HRegionInfo.getRegionNameAsStringForDisplay(r,
+               regionServer.getConfiguration());
+            </%java>
+            <td><a href="region.jsp?name=<% r.getEncodedName() %>"><% 
displayName %></a></td>
             <td><% Bytes.toStringBinary(HRegionInfo.getStartKeyForDisplay(r,
                                         regionServer.getConfiguration())) 
%></td>
             <td><% Bytes.toStringBinary(HRegionInfo.getEndKeyForDisplay(r,
@@ -123,9 +126,10 @@
         <tr>
         <%java>
             RegionLoad load = 
regionServer.createRegionLoad(r.getEncodedName());
+            String displayName = HRegionInfo.getRegionNameAsStringForDisplay(r,
+              regionServer.getConfiguration());
         </%java>
-            <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
-                                           regionServer.getConfiguration()) 
%></td>
+            <td><a href="region.jsp?name=<% r.getEncodedName() %>"><% 
displayName %></a></td>
             <%if load != null %>
             <td><% load.getReadRequestsCount() %></td>
             <td><% load.getWriteRequestsCount() %></td>
@@ -157,9 +161,10 @@
         <tr>
         <%java>
             RegionLoad load = 
regionServer.createRegionLoad(r.getEncodedName());
+            String displayName = HRegionInfo.getRegionNameAsStringForDisplay(r,
+              regionServer.getConfiguration());
         </%java>
-            <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
-                                           regionServer.getConfiguration()) 
%></td>
+            <td><a href="region.jsp?name=<% r.getEncodedName() %>"><% 
displayName %></a></td>
             <%if load != null %>
             <td><% load.getStores() %></td>
             <td><% load.getStorefiles() %></td>
@@ -197,9 +202,10 @@
             percentDone = String.format("%.2f", 100 *
             ((float) load.getCurrentCompactedKVs() / 
load.getTotalCompactingKVs())) + "%";
             }
+            String displayName = HRegionInfo.getRegionNameAsStringForDisplay(r,
+              regionServer.getConfiguration());
         </%java>
-            <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
-                                           regionServer.getConfiguration()) 
%></td>
+            <td><a href="region.jsp?name=<% r.getEncodedName() %>"><% 
displayName %></a></td>
             <%if load != null %>
             <td><% load.getTotalCompactingKVs() %></td>
             <td><% load.getCurrentCompactedKVs() %></td>
@@ -225,9 +231,10 @@
         <tr>
         <%java>
             RegionLoad load = 
regionServer.createRegionLoad(r.getEncodedName());
+            String displayName = HRegionInfo.getRegionNameAsStringForDisplay(r,
+              regionServer.getConfiguration());
         </%java>
-            <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
-                                           regionServer.getConfiguration()) 
%></td>
+            <td><a href="region.jsp?name=<% r.getEncodedName() %>"><% 
displayName %></a></td>
             <%if load != null %>
             <td><% load.getMemstoreSizeMB() %>m</td>
             </%if>

http://git-wip-us.apache.org/repos/asf/hbase/blob/2430efc2/hbase-server/src/main/resources/hbase-webapps/regionserver/region.jsp
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/resources/hbase-webapps/regionserver/region.jsp 
b/hbase-server/src/main/resources/hbase-webapps/regionserver/region.jsp
new file mode 100644
index 0000000..874ac43
--- /dev/null
+++ b/hbase-server/src/main/resources/hbase-webapps/regionserver/region.jsp
@@ -0,0 +1,130 @@
+<%--
+/**
+ * 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.Collection"
+  import="java.util.Date"
+  import="java.util.List"
+  import="static org.apache.commons.lang.StringEscapeUtils.escapeXml"
+  import="org.apache.hadoop.conf.Configuration"
+  import="org.apache.hadoop.hbase.HTableDescriptor"
+  import="org.apache.hadoop.hbase.HColumnDescriptor"
+  import="org.apache.hadoop.hbase.HBaseConfiguration"
+  import="org.apache.hadoop.hbase.HRegionInfo"
+  import="org.apache.hadoop.hbase.regionserver.HRegionServer"
+  import="org.apache.hadoop.hbase.regionserver.Region"
+  import="org.apache.hadoop.hbase.regionserver.Store"
+  import="org.apache.hadoop.hbase.regionserver.StoreFile"%>
+<%
+  String regionName = request.getParameter("name");
+  HRegionServer rs = (HRegionServer) 
getServletContext().getAttribute(HRegionServer.REGIONSERVER);
+  Configuration conf = rs.getConfiguration();
+
+  Region region = rs.getFromOnlineRegions(regionName);
+  String displayName = 
HRegionInfo.getRegionNameAsStringForDisplay(region.getRegionInfo(),
+    rs.getConfiguration());
+%>
+<!--[if IE]>
+<!DOCTYPE html>
+<![endif]-->
+<?xml version="1.0" encoding="UTF-8" ?>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>HBase RegionServer: <%= rs.getServerName() %></title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="description" content="">
+    <meta name="author" 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="/rs-status"><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="/rs-status">Home</a></li>
+                  <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>
+                  <% if (HBaseConfiguration.isShowConfInServlet()) { %>
+                  <li><a href="/conf">HBase Configuration</a></li>
+                  <% } %>
+              </ul>
+          </div><!--/.nav-collapse -->
+      </div>
+  </div>
+
+  <div class="container-fluid content">
+    <div class="row inner_header">
+        <div class="page-header">
+            <h1>Region: <%= displayName %></h1>
+        </div>
+    </div>
+
+<% if(region != null) { //
+     List<Store> stores = region.getStores();
+     for (Store store : stores) {
+       String cf = store.getColumnFamilyName();
+       Collection<StoreFile> storeFiles = store.getStorefiles(); %>
+
+       <h3>Column Family: <%= cf %></h2>
+
+       <h4>Memstore size (MB): <%= (int) (store.getMemStoreSize() / 1024 / 
1024) %></h3>
+
+       <h4>Store Files</h3>
+
+       <table class="table table-striped">
+         <tr>
+           <th>Store File</th>
+           <th>Size (MB)</th>
+           <th>Modification time</th>
+         </tr>
+       <%   for(StoreFile sf : storeFiles) { %>
+         <tr>
+           <td><a href="storeFile.jsp?name=<%= sf.getPath() %>"><%= 
sf.getPath() %></a></td>
+           <td><%= (int) (rs.getFileSystem().getLength(sf.getPath()) / 1024 / 
1024) %></td>
+           <td><%= new Date(sf.getModificationTimeStamp()) %></td>
+         </tr>
+         <% } %>
+
+         <p> <%= storeFiles.size() %> StoreFile(s) in set.</p>
+         </table>
+   <%  }
+   }%>
+</div>
+<script src="/static/js/jquery.min.js" type="text/javascript"></script>
+<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/hbase/blob/2430efc2/hbase-server/src/main/resources/hbase-webapps/regionserver/storeFile.jsp
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/resources/hbase-webapps/regionserver/storeFile.jsp 
b/hbase-server/src/main/resources/hbase-webapps/regionserver/storeFile.jsp
new file mode 100644
index 0000000..cbbb61f
--- /dev/null
+++ b/hbase-server/src/main/resources/hbase-webapps/regionserver/storeFile.jsp
@@ -0,0 +1,115 @@
+<%--
+/**
+ * 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.Collection"
+  import="java.util.Date"
+  import="java.util.List"
+  import="java.io.ByteArrayOutputStream"
+  import="java.io.PrintStream"
+  import="java.io.BufferedReader"
+  import="java.io.InputStreamReader"
+  import="org.apache.hadoop.conf.Configuration"
+  import="org.apache.hadoop.hbase.HBaseConfiguration"
+  import="org.apache.hadoop.hbase.io.hfile.HFilePrettyPrinter"
+  import="org.apache.hadoop.hbase.regionserver.HRegionServer"
+  import="org.apache.hadoop.hbase.regionserver.Region"
+  import="org.apache.hadoop.hbase.regionserver.Store"
+  import="org.apache.hadoop.hbase.regionserver.StoreFile"%>
+<%
+  String storeFile = request.getParameter("name");
+  HRegionServer rs = (HRegionServer) 
getServletContext().getAttribute(HRegionServer.REGIONSERVER);
+  Configuration conf = rs.getConfiguration();
+%>
+<!--[if IE]>
+<!DOCTYPE html>
+<![endif]-->
+<?xml version="1.0" encoding="UTF-8" ?>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>HBase RegionServer: <%= rs.getServerName() %></title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="description" content="">
+    <meta name="author" 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="/rs-status"><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="/rs-status">Home</a></li>
+                  <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>
+                  <% if (HBaseConfiguration.isShowConfInServlet()) { %>
+                  <li><a href="/conf">HBase Configuration</a></li>
+                  <% } %>
+              </ul>
+          </div><!--/.nav-collapse -->
+      </div>
+  </div>
+
+  <div class="container-fluid content">
+    <div class="row inner_header">
+        <div class="page-header">
+            <h4>StoreFile: <%= storeFile %></h4>
+        </div>
+    </div>
+    <pre>
+<%
+   try {
+     ProcessBuilder pb=new ProcessBuilder("hbase", "hfile", "-s", "-f", 
storeFile);
+     pb.redirectErrorStream(true);
+     Process pr = pb.start();
+     BufferedReader in = new BufferedReader(new 
InputStreamReader(pr.getInputStream()));
+     String line;
+     while ((line = in.readLine()) != null) {%>
+       <%= line %>
+     <%}
+     pr.waitFor();
+     in.close();
+   }
+   catch (Exception e) {%>
+     <%= e %>
+   <%}
+%>
+  </pre>
+</div>
+<script src="/static/js/jquery.min.js" type="text/javascript"></script>
+<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
+
+</body>
+</html>

Reply via email to