From c5cf80dc871510287c8d51faa343158c6710dda5 Mon Sep 17 00:00:00 2001 From: Archana Katiyar Date: Fri, 21 Sep 2018 21:04:53 +0530 Subject: [PATCH] HBASE-21207 Add client side sorting functionality in master web UI for table and region server details Signed-off-by: Andrew Purtell --- .../hbase/tmpl/master/MasterStatusTmpl.jamon | 20 +- .../tmpl/master/RegionServerListTmpl.jamon | 30 ++- .../resources/hbase-webapps/master/table.jsp | 235 ++---------------- .../hbase-webapps/static/css/asc.gif | Bin 0 -> 54 bytes .../resources/hbase-webapps/static/css/bg.gif | Bin 0 -> 64 bytes .../hbase-webapps/static/css/desc.gif | Bin 0 -> 54 bytes .../hbase-webapps/static/css/hbase.css | 16 +- .../static/js/jquery.tablesorter.min.js | 4 + pom.xml | 1 + 9 files changed, 88 insertions(+), 218 deletions(-) create mode 100644 hbase-server/src/main/resources/hbase-webapps/static/css/asc.gif create mode 100644 hbase-server/src/main/resources/hbase-webapps/static/css/bg.gif create mode 100644 hbase-server/src/main/resources/hbase-webapps/static/css/desc.gif create mode 100755 hbase-server/src/main/resources/hbase-webapps/static/js/jquery.tablesorter.min.js 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 408471a947b..efff6f70b81 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 @@ -356,8 +356,22 @@ AssignmentManager assignmentManager = master.getAssignmentManager(); + + @@ -420,7 +434,8 @@ AssignmentManager assignmentManager = master.getAssignmentManager(); } <%if (tables != null && tables.length > 0)%> - +
+ @@ -434,6 +449,8 @@ AssignmentManager assignmentManager = master.getAssignmentManager(); + + <%for HTableDescriptor htDesc : tables%> <%java> TableName tableName = htDesc.getTableName(); @@ -469,6 +486,7 @@ AssignmentManager assignmentManager = master.getAssignmentManager();

<% tables.length %> table(s) in set. [Details]

+
Namespace Table NameOther Regions Description
diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionServerListTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionServerListTmpl.jamon index 451cfa4d26e..29c0f77fa1a 100644 --- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionServerListTmpl.jamon +++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/RegionServerListTmpl.jamon @@ -77,7 +77,8 @@ Arrays.sort(serverNames); <%args> ServerName [] serverNames; - +
+ @@ -86,6 +87,8 @@ Arrays.sort(serverNames); + + <%java> int totalRegions = 0; int totalRequests = 0; @@ -124,6 +127,7 @@ Arrays.sort(serverNames); <%java> } + @@ -142,7 +146,8 @@ Arrays.sort(serverNames); <%args> ServerName [] serverNames; -
ServerName Start timeRequests Per Second Num. Regions
Total:<% servers.size() %>
+
+ @@ -150,6 +155,8 @@ Arrays.sort(serverNames); + + <%java> for (ServerName serverName: serverNames) { @@ -174,6 +181,7 @@ for (ServerName serverName: serverNames) { } } +
ServerName Used HeapMemstore Size
@@ -182,13 +190,16 @@ for (ServerName serverName: serverNames) { <%args> ServerName [] serverNames; - +
+ + + <%java> for (ServerName serverName: serverNames) { @@ -209,6 +220,7 @@ if (sl != null) { } } +
ServerName Request Per Second Read Request Count Write Request Count
@@ -217,7 +229,8 @@ if (sl != null) { <%args> ServerName [] serverNames; - +
+ @@ -227,6 +240,8 @@ if (sl != null) { + + <%java> for (ServerName serverName: serverNames) { @@ -254,6 +269,7 @@ if (sl != null) { } } +
ServerName Num. StoresIndex Size Bloom Size
@@ -261,7 +277,8 @@ if (sl != null) { <%args> ServerName [] serverNames; - +
+ @@ -269,6 +286,8 @@ if (sl != null) { + + <%java> for (ServerName serverName: serverNames) { @@ -295,6 +314,7 @@ if (sl.getTotalCompactingKVs() > 0) { } } +
ServerName Num. Compacting KVsRemaining KVs Compaction Progress
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 2d77e579f36..dd3924770f7 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp @@ -28,7 +28,6 @@ import="java.util.LinkedHashMap" import="java.util.Map" import="java.util.Collections" - import="java.util.Comparator" import="java.util.Collection" import="org.apache.commons.lang.StringEscapeUtils" import="org.apache.hadoop.conf.Configuration" @@ -60,11 +59,6 @@ MetaTableLocator metaTableLocator = new MetaTableLocator(); String fqtn = request.getParameter("name"); final String escaped_fqtn = StringEscapeUtils.escapeHtml(fqtn); - 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; @@ -164,10 +158,10 @@ if ( fqtn != null ) { table = new HTable(conf, fqtn); if (table.getTableDescriptor().getRegionReplication() > 1) { - tableHeader = "

Table Regions

"; + tableHeader = "

Table Regions

NameRegion ServerReadRequestsWriteRequestsStorefileSizeNum.StorefilesMemSizeLocalityStart KeyEnd KeyReplicaID
NameStart KeyEnd Key"; withReplica = true; } else { - tableHeader = "

Table Regions

Region ServerLocalityRequestsReplicaID
"; + tableHeader = "

Table Regions

NameRegion ServerReadRequestsWriteRequestsStorefileSizeNum.StorefilesMemSizeLocalityStart KeyEnd Key
NameStart KeyEnd Key"; } if ( !readOnly && action != null ) { %> @@ -219,6 +213,7 @@ if ( fqtn != null ) { if(fqtn.equals(TableName.META_TABLE_NAME.getNameAsString())) { %> <%= tableHeader %> + <% // NOTE: Presumes meta with one or more replicas for (int j = 0; j < numMetaReplicas; j++) { @@ -279,6 +274,7 @@ if ( fqtn != null ) { <% } %> <%} %> +
Region ServerLocalityRequests
<%} else { Admin admin = master.getConnection().getAdmin(); @@ -407,22 +403,8 @@ if ( fqtn != null ) { if(regions != null && regions.size() > 0) { %>

Table Regions

-Sort As - -Ascending -ShowDetailName&Start/End Key - -

- - +
+ @@ -441,161 +423,12 @@ ShowDetailName&Start/End Key>() { - public int compare( - Map.Entry entry1, - Map.Entry 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>() { - public int compare( - Map.Entry entry1, - Map.Entry 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>() { - public int compare( - Map.Entry entry1, - Map.Entry 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>() { - public int compare( - Map.Entry entry1, - Map.Entry 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>() { - public int compare( - Map.Entry entry1, - Map.Entry 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>() { - public int compare( - Map.Entry entry1, - Map.Entry 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; - } - }); - } - } numRegions = regions.size(); int numRegionsRendered = 0; // render all regions @@ -641,7 +474,7 @@ ShowDetailName&Start/End Key - + + <% if (withReplica) { %> @@ -673,6 +506,7 @@ ShowDetailName&Start/End Key +
Name(<%= String.format("%,1d", regions.size())%>) Region Server<%= escapeXml(showWhole?Bytes.toStringBinary(regionInfo.getEndKey()):"-")%><%= escapeXml(Bytes.toStringBinary(regionInfo.getStartKey()))%><%= escapeXml(Bytes.toStringBinary(regionInfo.getEndKey()))%>
Region ServerRegion CountPrimary Region Count
<% } else { %> -
Region ServerRegion CountPrimary Region Count
+
Region ServerRegion Count
+ <% } %> @@ -710,6 +545,7 @@ if (withReplica) { %> <% } %> +
Region ServerRegion Count
<% } } catch(Exception ex) { @@ -803,41 +639,18 @@ Actions: <% } %> + diff --git a/hbase-server/src/main/resources/hbase-webapps/static/css/asc.gif b/hbase-server/src/main/resources/hbase-webapps/static/css/asc.gif new file mode 100644 index 0000000000000000000000000000000000000000..74157867f25acbc146704d43399d6c3605ba7724 GIT binary patch literal 54 zcmZ?wbhEHb6lGvxXkcJa);0M5|G(l-7DfgJMg|=QAOOiQF!A=tFW`Q0{?_dDi`go= G4AuZ#-wosd literal 0 HcmV?d00001 diff --git a/hbase-server/src/main/resources/hbase-webapps/static/css/bg.gif b/hbase-server/src/main/resources/hbase-webapps/static/css/bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..fac668fcf42af844a3af0a239fa638ddbc08443c GIT binary patch literal 64 zcmZ?wbhEHb6lLIKXkcJa);0M5|G(l-7DfgJMg|=QAOOiQFp2l{H=O3Yl~fU8)V1~= QTew|n!uOuePzDBT00piR0RR91 literal 0 HcmV?d00001 diff --git a/hbase-server/src/main/resources/hbase-webapps/static/css/desc.gif b/hbase-server/src/main/resources/hbase-webapps/static/css/desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..3b30b3c58eabdb47a1c420ad03c8e30b966cc858 GIT binary patch literal 54 zcmZ?wbhEHb6lGvxXkcJa);0M5|G(l-7DfgJMg|=QAOOiQF!A>EGoD<#VNP?1QCB1* GgEatI(+xQQ literal 0 HcmV?d00001 diff --git a/hbase-server/src/main/resources/hbase-webapps/static/css/hbase.css b/hbase-server/src/main/resources/hbase-webapps/static/css/hbase.css index 03d8ff4f266..2169c234d5b 100644 --- a/hbase-server/src/main/resources/hbase-webapps/static/css/hbase.css +++ b/hbase-server/src/main/resources/hbase-webapps/static/css/hbase.css @@ -39,4 +39,18 @@ section { margin-bottom: 3em; } margin-top: 1.2em; } -/* Region Server page styling */ \ No newline at end of file +/* Region Server page styling */ + +/* sortable tables styling */ +table.tablesorter thead tr .header { + background-image: url(bg.gif); + background-repeat: no-repeat; + background-position: center right; + cursor: pointer; +} +table.tablesorter thead tr .headerSortUp { + background-image: url(asc.gif); +} +table.tablesorter thead tr .headerSortDown { + background-image: url(desc.gif); +} diff --git a/hbase-server/src/main/resources/hbase-webapps/static/js/jquery.tablesorter.min.js b/hbase-server/src/main/resources/hbase-webapps/static/js/jquery.tablesorter.min.js new file mode 100755 index 00000000000..ad84db6182d --- /dev/null +++ b/hbase-server/src/main/resources/hbase-webapps/static/js/jquery.tablesorter.min.js @@ -0,0 +1,4 @@ +/*! jQuery jquery.com | jquery.org/license */ +(function($){$.extend({tablesorter:new +function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",cssChildRow:"expand-child",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,sortLocaleCompare:true,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'/\.|\,/g',onRenderHeader:null,selectorHeaders:'thead th',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}if(table.tBodies.length==0)return;var rows=table.tBodies[0].rows;if(rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function checkHeaderOptionsSortingLocked(table,i){if((table.config.headers[i])&&(table.config.headers[i].lockedOrder))return table.config.headers[i].lockedOrder;return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;i b["+i+"]) ? 1 : 0));";};function makeSortTextDesc(i){return"((b["+i+"] < a["+i+"]) ? -1 : ((b["+i+"] > a["+i+"]) ? 1 : 0));";};function makeSortNumeric(i){return"a["+i+"]-b["+i+"];";};function makeSortNumericDesc(i){return"b["+i+"]-a["+i+"];";};function sortText(a,b){if(table.config.sortLocaleCompare)return a.localeCompare(b);return((ab)?1:0));};function sortTextDesc(a,b){if(table.config.sortLocaleCompare)return b.localeCompare(a);return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$.data(this,"tablesorter",config);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){$this.trigger("sortStart");var $cell=$(this);var i=this.column;this.order=this.count++%2;if(this.lockedOrder)this.order=this.lockedOrder;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i**/src/main/asciidoc/hbase.css **/jquery.min.js + */jquery.tablesorter.min.js **/*.vm