HBASE-15675 Add more details about region on table.jsp

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

Branch: refs/heads/hbase-12439
Commit: 082d193455125f451d3fc1a63146ca024899dd0f
Parents: c77a153
Author: Yu Li <l...@apache.org>
Authored: Tue May 3 12:00:09 2016 +0800
Committer: Yu Li <l...@apache.org>
Committed: Tue May 3 20:18:48 2016 +0800

----------------------------------------------------------------------
 .../resources/hbase-webapps/master/table.jsp    | 361 +++++++++++++++++--
 1 file changed, 335 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/082d1934/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
----------------------------------------------------------------------
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 693a663..ee2a7ba 100644
--- a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
@@ -19,13 +19,19 @@
 --%>
 <%@ page contentType="text/html;charset=UTF-8"
   import="static org.apache.commons.lang.StringEscapeUtils.escapeXml"
+  import="com.google.protobuf.ByteString"
+  import="java.util.ArrayList"
   import="java.util.TreeMap"
   import="java.util.List"
+  import="java.util.LinkedHashMap"
   import="java.util.Map"
   import="java.util.Set"
   import="java.util.Collection"
+  import="java.util.Collections"
+  import="java.util.Comparator"
   import="org.owasp.esapi.ESAPI"
   import="org.apache.hadoop.conf.Configuration"
+  import="org.apache.hadoop.util.StringUtils"
   import="org.apache.hadoop.hbase.client.HTable"
   import="org.apache.hadoop.hbase.client.Admin"
   import="org.apache.hadoop.hbase.client.CompactionState"
@@ -40,6 +46,8 @@
   import="org.apache.hadoop.hbase.zookeeper.MetaTableLocator"
   import="org.apache.hadoop.hbase.util.Bytes"
   import="org.apache.hadoop.hbase.util.FSUtils"
+  import="org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos"
+  import="org.apache.hadoop.hbase.protobuf.generated.HBaseProtos"
   import="org.apache.hadoop.hbase.TableName"
   import="org.apache.hadoop.hbase.HColumnDescriptor"
   import="org.apache.hadoop.hbase.client.RegionReplicaUtil"
@@ -51,6 +59,11 @@
 
   MetaTableLocator metaTableLocator = new MetaTableLocator();
   String fqtn = request.getParameter("name");
+  String sortKey = request.getParameter("sort");
+  String reverse = request.getParameter("reverse");
+  final boolean reverseOrder = (reverse==null||!reverse.equals("false"));
+  String showWholeKey = request.getParameter("showwhole");
+  final boolean showWhole = (showWholeKey!=null && 
showWholeKey.equals("true"));
   HTable table = null;
   String tableHeader;
   boolean withReplica = false;
@@ -130,10 +143,10 @@ if ( fqtn != null ) {
   try {
   table = (HTable) master.getConnection().getTable(TableName.valueOf(fqtn));
   if (table.getTableDescriptor().getRegionReplication() > 1) {
-    tableHeader = "<h2>Table Regions</h2><table class=\"table table-striped\" 
style=\"table-layout: fixed; word-wrap: break-word;\"><tr><th 
style=\"width:22%\">Name</th><th>Region Server</th><th 
style=\"width:22%\">Start Key</th><th style=\"width:22%\">End 
Key</th><th>Locality</th><th>Requests</th><th>ReplicaID</th></tr>";
+    tableHeader = "<h2>Table Regions</h2><table class=\"table table-striped\" 
style=\"table-layout: fixed; word-wrap: 
break-word;\"><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>Locality</th><th>Start
 Key</th><th>End Key</th><th>ReplicaID</th></tr>";
     withReplica = true;
   } else {
-    tableHeader = "<h2>Table Regions</h2><table class=\"table table-striped\" 
style=\"table-layout: fixed; word-wrap: break-word;\"><tr><th 
style=\"width:22%\">Name</th><th>Region Server</th><th 
style=\"width:22%\">Start Key</th><th style=\"width:22%\">End 
Key</th><th>Locality</th><th>Requests</th></tr>";
+    tableHeader = "<h2>Table Regions</h2><table class=\"table table-striped\" 
style=\"table-layout: fixed; word-wrap: 
break-word;\"><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>Locality</th><th>Start
 Key</th><th>End Key</th></tr>";
   }
   if ( !readOnly && action != null ) {
 %>
@@ -187,16 +200,42 @@ if ( fqtn != null ) {
                             HRegionInfo.FIRST_META_REGIONINFO, j);
     ServerName metaLocation = 
metaTableLocator.waitMetaRegionLocation(master.getZooKeeper(), j, 1);
     for (int i = 0; i < 1; i++) {
-      String url = "//" + metaLocation.getHostname() + ":" +
-                   master.getRegionServerInfoPort(metaLocation) + "/";
+      String url = "";
+      String readReq = "N/A";
+      String writeReq = "N/A";
+      String fileSize = "N/A";
+      String fileCount = "N/A";
+      String memSize = "N/A";
+      float locality = 0.0f;
+
+      if (metaLocation != null) {
+        ServerLoad sl = master.getServerManager().getLoad(metaLocation);
+        url = "//" + metaLocation.getHostname() + ":" + 
master.getRegionServerInfoPort(metaLocation) + "/";
+        if (sl != null) {
+          Map<byte[], RegionLoad> map = sl.getRegionsLoad();
+          if (map.containsKey(meta.getRegionName())) {
+            RegionLoad load = map.get(meta.getRegionName());
+            readReq = String.format("%,1d", load.getReadRequestsCount());
+            writeReq = String.format("%,1d", load.getWriteRequestsCount());
+            fileSize = 
StringUtils.byteDesc(load.getStorefileSizeMB()*1024l*1024);
+            fileCount = String.format("%,1d", load.getStorefiles());
+            memSize = 
StringUtils.byteDesc(load.getMemStoreSizeMB()*1024l*1024);
+            locality = load.getDataLocality();
+          }
+        }
+      }
 %>
 <tr>
   <td><%= escapeXml(meta.getRegionNameAsString()) %></td>
     <td><a href="<%= url %>"><%= metaLocation.getHostname().toString() + ":" + 
master.getRegionServerInfoPort(metaLocation) %></a></td>
+    <td><%= readReq%></td>
+    <td><%= writeReq%></td>
+    <td><%= fileSize%></td>
+    <td><%= fileCount%></td>
+    <td><%= memSize%></td>
+    <td><%= locality%></td>
     <td><%= escapeXml(Bytes.toString(meta.getStartKey())) %></td>
     <td><%= escapeXml(Bytes.toString(meta.getEndKey())) %></td>
-    <td>-</td>
-    <td>-</td>
 </tr>
 <%  } %>
 <%} %>
@@ -280,27 +319,265 @@ if ( fqtn != null ) {
   <% } %>
 </table>
 <%
+  long totalReadReq = 0;
+  long totalWriteReq = 0;
+  long totalSize = 0;
+  long totalStoreFileCount = 0;
+  long totalMemSize = 0;
+  String urlRegionServer = null;
   Map<ServerName, Integer> regDistribution = new TreeMap<ServerName, 
Integer>();
   Map<ServerName, Integer> primaryRegDistribution = new TreeMap<ServerName, 
Integer>();
   List<HRegionLocation> regions = r.getAllRegionLocations();
-  if(regions != null && regions.size() > 0) { %>
-<%=     tableHeader %>
-<%
+  Map<HRegionInfo, RegionLoad> regionsToLoad = new LinkedHashMap<HRegionInfo, 
RegionLoad>();
+  Map<HRegionInfo, ServerName> regionsToServer = new 
LinkedHashMap<HRegionInfo, ServerName>();
   for (HRegionLocation hriEntry : regions) {
     HRegionInfo regionInfo = hriEntry.getRegionInfo();
     ServerName addr = hriEntry.getServerName();
-    long req = 0;
-    float locality = 0.0f;
-    String urlRegionServer = null;
+    regionsToServer.put(regionInfo, addr);
 
     if (addr != null) {
       ServerLoad sl = master.getServerManager().getLoad(addr);
       if (sl != null) {
         Map<byte[], RegionLoad> map = sl.getRegionsLoad();
-        if (map.containsKey(regionInfo.getRegionName())) {
-          req = map.get(regionInfo.getRegionName()).getRequestsCount();
-          locality = map.get(regionInfo.getRegionName()).getDataLocality();
+        RegionLoad regionload = map.get(regionInfo.getRegionName());
+        regionsToLoad.put(regionInfo, regionload);
+        if(regionload != null) {
+          totalReadReq += regionload.getReadRequestsCount();
+          totalWriteReq += regionload.getWriteRequestsCount();
+          totalSize += regionload.getStorefileSizeMB();
+          totalStoreFileCount += regionload.getStorefiles();
+          totalMemSize += regionload.getMemStoreSizeMB();
+        } else {
+          RegionLoad load0 = new 
RegionLoad(ClusterStatusProtos.RegionLoad.newBuilder().setRegionSpecifier(HBaseProtos.RegionSpecifier.newBuilder().setValue(ByteString.copyFrom(regionInfo.getRegionName())).build()).build());
+          regionsToLoad.put(regionInfo, load0);
         }
+      }else{
+        RegionLoad load0 = new 
RegionLoad(ClusterStatusProtos.RegionLoad.newBuilder().setRegionSpecifier(HBaseProtos.RegionSpecifier.newBuilder().setValue(ByteString.copyFrom(regionInfo.getRegionName())).build()).build());
+        regionsToLoad.put(regionInfo, load0);
+      }
+    }else{
+      RegionLoad load0 = new 
RegionLoad(ClusterStatusProtos.RegionLoad.newBuilder().setRegionSpecifier(HBaseProtos.RegionSpecifier.newBuilder().setValue(ByteString.copyFrom(regionInfo.getRegionName())).build()).build());
+      regionsToLoad.put(regionInfo, load0);
+    }
+  }
+
+  if(regions != null && regions.size() > 0) { %>
+<h2>Table Regions</h2>
+Sort As
+<select id="sel" style="margin-right: 10px">
+<option value="regionName">RegionName</option>
+<option value="readrequest">ReadRequest</option>
+<option value="writerequest">WriteRequest</option>
+<option value="size">StorefileSize</option>
+<option value="filecount">Num.Storefiles</option>
+<option value="memstore">MemstoreSize</option>
+<option value="locality">Locality</option>
+</select>
+Ascending<input type="checkbox" id="ascending" value="Ascending" 
style="margin-right:10px">
+ShowDetailName&Start/End Key<input type="checkbox" id="showWhole" 
style="margin-right:10px">
+<input type="button" id="submit" value="Reorder" onClick="reloadAsSort()" 
style="font-size: 12pt; width: 5em; margin-bottom: 5px" class="btn">
+<p>
+
+<table class="table table-striped">
+<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>(<%= StringUtils.byteDesc(totalSize*1024l*1024)%>)</th>
+<th>Num.Storefiles<br>(<%= String.format("%,1d", totalStoreFileCount)%>)</th>
+<th>MemSize<br>(<%= StringUtils.byteDesc(totalMemSize*1024l*1024)%>)</th>
+<th>Locality</th>
+<th>Start Key</th>
+<th>End Key</th>
+<%
+  if (withReplica) {
+%>
+<th>ReplicaID</th>
+<%
+  }
+%>
+</tr>
+
+<%
+  List<Map.Entry<HRegionInfo, RegionLoad>> entryList = new 
ArrayList<Map.Entry<HRegionInfo, RegionLoad>>(regionsToLoad.entrySet());
+  if(sortKey != null) {
+    if (sortKey.equals("readrequest")) {
+      Collections.sort(entryList,
+          new Comparator<Map.Entry<HRegionInfo, RegionLoad>>() {
+            public int compare(
+                Map.Entry<HRegionInfo, RegionLoad> entry1,
+                Map.Entry<HRegionInfo, RegionLoad> entry2) {
+              if (entry1 == null || entry1.getValue() == null) {
+                return -1;
+              } else if (entry2 == null || entry2.getValue() == null) {
+                return 1;
+              }
+              int result = 0;
+              if (entry1.getValue().getReadRequestsCount() < 
entry2.getValue().getReadRequestsCount()) {
+                result = -1;
+              } else if (entry1.getValue().getReadRequestsCount() > 
entry2.getValue().getReadRequestsCount()) {
+                result = 1;
+              }
+              if (reverseOrder) {
+                result = -1 * result;
+              }
+              return result;
+            }
+          });
+    } else if (sortKey.equals("writerequest")) {
+      Collections.sort(entryList,
+          new Comparator<Map.Entry<HRegionInfo, RegionLoad>>() {
+            public int compare(
+                Map.Entry<HRegionInfo, RegionLoad> entry1,
+                Map.Entry<HRegionInfo, RegionLoad> entry2) {
+              if (entry1 == null || entry1.getValue() == null) {
+                return -1;
+              } else if (entry2 == null || entry2.getValue() == null) {
+                return 1;
+              }
+              int result = 0;
+              if (entry1.getValue().getWriteRequestsCount() < entry2.getValue()
+                  .getWriteRequestsCount()) {
+                result = -1;
+              } else if (entry1.getValue().getWriteRequestsCount() > 
entry2.getValue()
+                  .getWriteRequestsCount()) {
+                result = 1;
+              }
+              if (reverseOrder) {
+                result = -1 * result;
+              }
+              return result;
+            }
+          });
+    } else if (sortKey.equals("size")) {
+      Collections.sort(entryList,
+          new Comparator<Map.Entry<HRegionInfo, RegionLoad>>() {
+            public int compare(
+                Map.Entry<HRegionInfo, RegionLoad> entry1,
+                Map.Entry<HRegionInfo, RegionLoad> entry2) {
+              if (entry1 == null || entry1.getValue() == null) {
+                return -1;
+              } else if (entry2 == null || entry2.getValue() == null) {
+                return 1;
+              }
+              int result = 0;
+              if (entry1.getValue().getStorefileSizeMB() < entry2.getValue()
+                  .getStorefileSizeMB()) {
+                result = -1;
+              } else if (entry1.getValue().getStorefileSizeMB() > entry2
+                  .getValue().getStorefileSizeMB()) {
+                result = 1;
+              }
+              if (reverseOrder) {
+                result = -1 * result;
+              }
+              return result;
+            }
+          });
+    } else if (sortKey.equals("filecount")) {
+      Collections.sort(entryList,
+          new Comparator<Map.Entry<HRegionInfo, RegionLoad>>() {
+            public int compare(
+                Map.Entry<HRegionInfo, RegionLoad> entry1,
+                Map.Entry<HRegionInfo, RegionLoad> entry2) {
+              if (entry1 == null || entry1.getValue() == null) {
+                return -1;
+              } else if (entry2 == null || entry2.getValue() == null) {
+                return 1;
+              }
+              int result = 0;
+              if (entry1.getValue().getStorefiles() < entry2.getValue()
+                  .getStorefiles()) {
+                result = -1;
+              } else if (entry1.getValue().getStorefiles() > entry2.getValue()
+                  .getStorefiles()) {
+                result = 1;
+              }
+              if (reverseOrder) {
+                result = -1 * result;
+              }
+              return result;
+            }
+          });
+    } else if (sortKey.equals("memstore")) {
+      Collections.sort(entryList,
+          new Comparator<Map.Entry<HRegionInfo, RegionLoad>>() {
+            public int compare(
+                Map.Entry<HRegionInfo, RegionLoad> entry1,
+                Map.Entry<HRegionInfo, RegionLoad> entry2) {
+              if (entry1 == null || entry1.getValue()==null) {
+                return -1;
+              } else if (entry2 == null || entry2.getValue()==null) {
+                return 1;
+              }
+              int result = 0;
+              if (entry1.getValue().getMemStoreSizeMB() < entry2.getValue()
+                  .getMemStoreSizeMB()) {
+                result = -1;
+              } else if (entry1.getValue().getMemStoreSizeMB() > entry2
+                  .getValue().getMemStoreSizeMB()) {
+                result = 1;
+              }
+              if (reverseOrder) {
+                result = -1 * result;
+              }
+              return result;
+            }
+          });
+    } else if (sortKey.equals("locality")) {
+      Collections.sort(entryList,
+          new Comparator<Map.Entry<HRegionInfo, RegionLoad>>() {
+            public int compare(
+                Map.Entry<HRegionInfo, RegionLoad> entry1,
+                Map.Entry<HRegionInfo, RegionLoad> entry2) {
+              if (entry1 == null || entry1.getValue()==null) {
+                return -1;
+              } else if (entry2 == null || entry2.getValue()==null) {
+                return 1;
+              }
+              int result = 0;
+              if (entry1.getValue().getDataLocality() < entry2.getValue()
+                  .getDataLocality()) {
+                result = -1;
+              } else if (entry1.getValue().getDataLocality() > entry2
+                  .getValue().getDataLocality()) {
+                result = 1;
+              }
+              if (reverseOrder) {
+                result = -1 * result;
+              }
+              return result;
+            }
+          });
+    }
+  }
+
+  for (Map.Entry<HRegionInfo, RegionLoad> hriEntry : entryList) {
+    HRegionInfo regionInfo = hriEntry.getKey();
+    ServerName addr = regionsToServer.get(regionInfo);
+    RegionLoad load = hriEntry.getValue();
+    String readReq = "N/A";
+    String writeReq = "N/A";
+    String regionSize = "N/A";
+    String fileCount = "N/A";
+    String memSize = "N/A";
+    float locality = 0.0f;
+    if(load != null) {
+      readReq = String.format("%,1d", load.getReadRequestsCount());
+      writeReq = String.format("%,1d", load.getWriteRequestsCount());
+      regionSize = StringUtils.byteDesc(load.getStorefileSizeMB()*1024l*1024);
+      fileCount = String.format("%,1d", load.getStorefiles());
+      memSize = StringUtils.byteDesc(load.getMemStoreSizeMB()*1024l*1024);
+      locality = load.getDataLocality();
+    }
+
+    if (addr != null) {
+      ServerLoad sl = master.getServerManager().getLoad(addr);
+      // This port might be wrong if RS actually ended up using something else.
+      urlRegionServer =
+          "//" + addr.getHostname() + ":" + 
master.getRegionServerInfoPort(addr) + "/";
+      if(sl != null) {
         Integer i = regDistribution.get(addr);
         if (null == i) i = Integer.valueOf(0);
         regDistribution.put(addr, i + 1);
@@ -313,14 +590,12 @@ if ( fqtn != null ) {
     }
 %>
 <tr>
-  <td><%= 
escapeXml(Bytes.toStringBinary(HRegionInfo.getRegionNameForDisplay(regionInfo,
-                    conf))) %></td>
+  <td><%= 
escapeXml(showWhole?Bytes.toStringBinary(regionInfo.getRegionName()):regionInfo.getEncodedName())
 %></td>
   <%
-  if (addr != null) {
-    String url = "//" + addr.getHostname() + ":" + 
master.getRegionServerInfoPort(addr) + "/rs-status";
+  if (urlRegionServer != null) {
   %>
   <td>
-     <a href="<%= url %>"><%= addr.getHostname().toString() + ":" + 
addr.getPort() %></a>
+     <a href="<%= urlRegionServer %>"><%= addr.getHostname().toString() + ":" 
+ master.getRegionServerInfoPort(addr) %></a>
   </td>
   <%
   } else {
@@ -329,12 +604,14 @@ if ( fqtn != null ) {
   <%
   }
   %>
-  <td><%= 
escapeXml(Bytes.toStringBinary(HRegionInfo.getStartKeyForDisplay(regionInfo,
-                    conf))) %></td>
-  <td><%= 
escapeXml(Bytes.toStringBinary(HRegionInfo.getEndKeyForDisplay(regionInfo,
-                    conf))) %></td>
+  <td><%= readReq%></td>
+  <td><%= writeReq%></td>
+  <td><%= regionSize%></td>
+  <td><%= fileCount%></td>
+  <td><%= memSize%></td>
   <td><%= locality%></td>
-  <td><%= req%></td>
+  <td><%= 
escapeXml(showWhole?Bytes.toStringBinary(regionInfo.getStartKey()):"-")%></td>
+  <td><%= 
escapeXml(showWhole?Bytes.toStringBinary(regionInfo.getEndKey()):"-")%></td>
   <%
   if (withReplica) {
   %>
@@ -363,7 +640,7 @@ if (withReplica) {
      String url = "//" + addr.getHostname() + ":" + 
master.getRegionServerInfoPort(addr) + "/";
 %>
 <tr>
-  <td><a href="<%= url %>"><%= addr.getHostname().toString() + ":" + 
addr.getPort() %></a></td>
+  <td><a href="<%= url %>"><%= addr.getHostname().toString() + ":" + 
master.getRegionServerInfoPort(addr) %></a></td>
   <td><%= rdEntry.getValue()%></td>
 <%
 if (withReplica) {
@@ -465,3 +742,35 @@ Actions:
 
 </body>
 </html>
+
+<script>
+var index=0;
+var sortKeyValue='<%= sortKey %>';
+if(sortKeyValue=="readrequest")index=1;
+else if(sortKeyValue=="writerequest")index=2;
+else if(sortKeyValue=="size")index=3;
+else if(sortKeyValue=="filecount")index=4;
+else if(sortKeyValue=="memstore")index=5;
+else if(sortKeyValue=="locality")index=6;
+document.getElementById("sel").selectedIndex=index;
+
+var reverse='<%= reverseOrder %>';
+if(reverse=='false')document.getElementById("ascending").checked=true;
+
+var showWhole='<%= showWhole %>';
+if(showWhole=='true')document.getElementById("showWhole").checked=true;
+
+function reloadAsSort(){
+  var url="?name="+'<%= fqtn %>';
+  if(document.getElementById("sel").selectedIndex>0){
+    url=url+"&sort="+document.getElementById("sel").value;
+  }
+  if(document.getElementById("ascending").checked){
+    url=url+"&reverse=false";
+  }
+  if(document.getElementById("showWhole").checked){
+    url=url+"&showwhole=true";
+  }
+  location.href=url;
+}
+</script>

Reply via email to