This is an automated email from the ASF dual-hosted git repository. domgarguilo pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/main by this push: new 37a5babfa3 Convert tables in monitor `/manager` page to DataTables (#2703) 37a5babfa3 is described below commit 37a5babfa31e76063b7e40d9ff3a4008eb2d5605 Author: Dom G <dominic.gargu...@gmail.com> AuthorDate: Fri May 20 10:57:52 2022 -0400 Convert tables in monitor `/manager` page to DataTables (#2703) * Convert tables to datatables * Create function for reloading datatable in functions.js * Apply formatting --- .../accumulo/monitor/resources/js/functions.js | 13 ++ .../accumulo/monitor/resources/js/manager.js | 257 ++++++++++++--------- .../accumulo/monitor/resources/js/tservers.js | 13 +- .../apache/accumulo/monitor/templates/manager.ftl | 74 +++--- .../apache/accumulo/monitor/templates/tables.ftl | 4 +- 5 files changed, 199 insertions(+), 162 deletions(-) diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/functions.js b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/functions.js index 08b22a72da..46beeb6ab9 100644 --- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/functions.js +++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/functions.js @@ -268,6 +268,19 @@ function createEmptyRow(col, msg) { return '<td class="center" colspan="' + col + '"><i>' + msg + '</i></td>'; } +/** + * Performs an ajax reload for the given DataTable + * + * @param {DataTable} table DataTable to perform an ajax reload on + */ +function ajaxReloadTable(table) { + if (table) { + table.ajax.reload(null, false); // user paging is not reset on reload + } else { + console.error('There was an error reloading the given table'); + } +} + /** * Performs GET call and builds console logging message from data received * @param {string} call REST url called diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/manager.js b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/manager.js index 37e22d5f2b..32d2b6407b 100644 --- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/manager.js +++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/manager.js @@ -16,31 +16,44 @@ * specific language governing permissions and limitations * under the License. */ +/* JSLint global definitions */ +/*global + $, document, sessionStorage, getManager, bigNumberForQuantity, + timeDuration, dateFormat, getStatus, ajaxReloadTable +*/ "use strict"; -/** - * Creates manager initial table - */ -$(document).ready(function() { - refreshManager(); -}); +var managerStatusTable, recoveryListTable; + +function refreshManagerBanner() { + getStatus().then(function () { + var managerStatus = JSON.parse(sessionStorage.status).managerStatus; + + // If manager status is error + if (managerStatus === 'ERROR') { + // show banner and hide table + $('#managerBanner').show(); + $('#managerStatus_wrapper').hide(); + } else { + // otherwise, hide banner and show table + $('#managerBanner').hide(); + $('#managerStatus_wrapper').show(); + } + }); +} /** - * Makes the REST calls, generates the tables with the new information + * Populates tables with the new information */ -function refreshManager() { - getManager().then(function() { - refreshManagerTable(); - }); - getRecoveryList().then(function() { - recoveryList(); - }); +function refreshManagerTables() { + ajaxReloadTable(managerStatusTable); + refreshManagerBanner(); + ajaxReloadTable(recoveryListTable); } - /* - * The tables refresh function will do this functionality - * If tables are removed from Manager, uncomment this function + * The tables.ftl refresh function will do this functionality. + * If tables are removed from Manager, uncomment this function. */ /** * Used to redraw the page @@ -50,98 +63,124 @@ function refreshManager() { }*/ /** - * Creates recovery list table - */ -function recoveryList() { - /* - * Get the recovery value obtained earlier, - * if it doesn't exists, create an empty array - */ - var data = sessionStorage.recoveryList === undefined ? - [] : JSON.parse(sessionStorage.recoveryList); - - clearTableBody('recoveryList'); - - // If there is no recovery list data, hide the table - if (data.length === 0 || data.recoveryList.length === 0) { - $('#recoveryList').hide(); - } else { - $('#recoveryList').show(); - - // Creates the table for the recovery list - $.each(data.recoveryList, function(key, val) { - var items = []; - items.push(createFirstCell(val.server, val.server)); - items.push(createRightCell(val.log, val.log)); - var duration = timeDuration(parseInt(val.time)); - items.push(createRightCell(val.time, duration)); - var percentProgress = (val.progress * 100).toFixed(2) + '%'; - items.push(createRightCell(val.progress, percentProgress)); - - $('<tr/>', { - html: items.join('') - }).appendTo('#recoveryList tbody'); - }); - } -} - -/** - * Generates the manager table + * Creates initial tables */ -function refreshManagerTable() { - // Gets the manager status - var status = JSON.parse(sessionStorage.status).managerStatus; - - // Hide the banner and the manager table - $('#managerBanner').hide(); - clearTableBody('managerStatus'); - $('#managerStatus').hide(); - - // If manager status is error, show banner, otherwise, create manager table - if (status === 'ERROR') { - $('#managerBanner').show(); - } else { - $('#managerStatus').show(); - var data = JSON.parse(sessionStorage.manager); - var items = []; - items.push(createFirstCell(data.manager, data.manager)); - - items.push(createRightCell(data.onlineTabletServers, - data.onlineTabletServers)); - - items.push(createRightCell(data.totalTabletServers, - data.totalTabletServers)); - var date = data.lastGC; - //this will be a finish time or a status of Running, Waiting, or down - if (!isNaN(date)) - date = new Date(parseInt(data.lastGC)).toLocaleString().split(' ').join(' '); - - items.push(createLeftCell(data.lastGC, '<a href="/gc">' + date + '</a>')); - - items.push(createRightCell(data.tablets, - bigNumberForQuantity(data.tablets))); - - items.push(createRightCell(data.unassignedTablets, - bigNumberForQuantity(data.unassignedTablets))); - - items.push(createRightCell(data.numentries, - bigNumberForQuantity(data.numentries))); - - items.push(createRightCell(data.ingestrate, - bigNumberForQuantity(Math.round(data.ingestrate)))); - - items.push(createRightCell(data.entriesRead, - bigNumberForQuantity(Math.round(data.entriesRead)))); - - items.push(createRightCell(data.queryrate, - bigNumberForQuantity(Math.round(data.queryrate)))); - - items.push(createRightCell(data.holdTime, timeDuration(data.holdTime))); +$(document).ready(function () { + + // Generates the manager table + managerStatusTable = $('#managerStatus').DataTable({ + "ajax": { + "url": '/rest/manager', + "dataSrc": function (json) { + // the data needs to be in an array to work with DataTables + var arr = [json]; + return arr; + } + }, + "stateSave": true, + "searching": false, + "paging": false, + "info": false, + "columnDefs": [ + { + "targets": "big-num", + "render": function (data, type) { + if (type === 'display') { + data = bigNumberForQuantity(data); + } + return data; + } + }, + { + "targets": "big-num-rounded", + "render": function (data, type) { + if (type === 'display') { + data = bigNumberForQuantity(Math.round(data)); + } + return data; + } + }, + { + "targets": "duration", + "render": function (data, type) { + if (type === 'display') { + data = timeDuration(parseInt(data, 10)); + } + return data; + } + } + ], + "columns": [ + { "data": "manager" }, + { "data": "onlineTabletServers" }, + { "data": "totalTabletServers" }, + { + "data": "lastGC", + "type": "html", + "render": function (data, type) { + if (type === 'display') { + if (data !== 'Waiting') { + data = dateFormat(parseInt(data, 10)); + } + data = '<a href="/gc">' + data + '</a>'; + } + return data; + } + }, + { "data": "tablets" }, + { "data": "unassignedTablets" }, + { "data": "numentries" }, + { "data": "ingestrate" }, + { "data": "entriesRead" }, + { "data": "queryrate" }, + { "data": "holdTime" }, + { "data": "osload" }, + ] + }); - items.push(createRightCell(data.osload, bigNumberForQuantity(data.osload))); + // Generates the recovery table + recoveryListTable = $('#recoveryList').DataTable({ + "ajax": { + "url": '/rest/tservers/recovery', + "dataSrc": function (data) { + data = data.recoveryList; + if (data.length === 0) { + console.info('Recovery list is empty, hiding recovery table'); + $('#recoveryList_wrapper').hide(); + } else { + $('#recoveryList_wrapper').show(); + } + return data; + } + }, + "columnDefs": [ + { + "targets": "duration", + "render": function (data, type) { + if (type === 'display') { + data = timeDuration(parseInt(data, 10)); + } + return data; + } + }, + { + "targets": "percent", + "render": function (data, type) { + if (type === 'display') { + data = (data * 100).toFixed(2) + '%'; + } + return data; + } + } + ], + "stateSave": true, + "columns": [ + { "data": "server" }, + { "data": "log" }, + { "data": "time" }, + { "data": "progress" } + ] + }); - $('<tr/>', { - html: items.join('') - }).appendTo('#managerStatus tbody'); - } -} + refreshManagerTables(); +}); \ No newline at end of file diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/tservers.js b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/tservers.js index 47d2bb7d66..53624cae03 100644 --- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/tservers.js +++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/tservers.js @@ -19,7 +19,7 @@ /* JSLint global definitions */ /*global $, document, sessionStorage, getTServers, clearDeadServers, refreshNavBar, - getRecoveryList, bigNumberForQuantity, timeDuration, dateFormat + getRecoveryList, bigNumberForQuantity, timeDuration, dateFormat, ajaxReloadTable */ "use strict"; @@ -63,17 +63,6 @@ function refreshRecoveryList() { }); } -/** - * Performs an ajax reload for the given Datatable - * - * @param {DataTable} table DataTable to perform an ajax reload on - */ -function ajaxReloadTable(table) { - if (table) { - table.ajax.reload(null, false); // user paging is not reset on reload - } -} - /** * Refreshes data in the tserver table */ diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/manager.ftl b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/manager.ftl index bde976ecd4..641a3bfea0 100644 --- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/manager.ftl +++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/manager.ftl @@ -18,48 +18,44 @@ under the License. --> - <div class="row"> - <div class="col-xs-12"> - <h3>${title}</h3> - </div> - </div> - <div id="managerBanner" style="display: none;"><div class="alert alert-danger" role="alert">Manager Server Not Running</div></div> - <div class="row"> - <div class="col-xs-12"> - <table id="managerStatus" class="table table-bordered table-striped table-condensed"> - <thead> - <tr> + <div id="managerBanner" style="display: none;"> + <div class="alert alert-danger" role="alert">Manager Server Not Running</div> + </div> + <table id="managerStatus" class="table table-bordered table-striped table-condensed"> + <caption><span class="table-caption">${title}</span><br /></caption> + <thead> + <tr> <th class="firstcell" title="The hostname of the manager server">Hostname</th> <th title="Number of tablet servers currently available">Online TServers </th> <th title="The total number of tablet servers configured">TotalTServers </th> <th title="The last time files were cleaned-up from HDFS.">Last GC</th> - <th title="Tables are broken down into ranges of rows called tablets.">Tablets</th> - <th>Unassigned Tablets </th> - <th title="The total number of key/value pairs in Accumulo">Entries</th> - <th title="The number of Key/Value pairs inserted. (Note that deletes are considered inserted)">Ingest</th> - <th title="The total number of Key/Value pairs read on the server side. Not all may be returned because of filtering.">Entries Read</th> - <th title="The total number of Key/Value pairs returned as a result of scans.">Entries Returned</th> - <th title="The maximum amount of time that ingest has been held across all servers due to a lack of memory to store the records">Hold Time</th> - <th title="The Unix one minute load average. The average number of processes in the run queue over a one minute interval.">OS Load</th> - </tr> - </thead> - <tbody></tbody> - </table> - <table id="recoveryList" class="table table-bordered table-striped table-condensed"> - <caption><span class="table-caption">Log Recovery</span><br/> - <span class="table-subcaption">Some tablets were unloaded in an unsafe manner. Write-ahead logs are being recovered.</span><br/> - </caption> - <thead> - <tr> + <th class="big-num" title="Tables are broken down into ranges of rows called tablets.">Tablets</th> + <th class="big-num">Unassigned Tablets </th> + <th class="big-num" title="The total number of key/value pairs in Accumulo">Entries</th> + <th class="big-num-rounded" title="The number of Key/Value pairs inserted. (Note that deletes are considered inserted)">Ingest</th> + <th class="big-num-rounded" title="The total number of Key/Value pairs read on the server side. Not all may be returned because of filtering.">Entries Read</th> + <th class="big-num-rounded" title="The total number of Key/Value pairs returned as a result of scans.">Entries Returned</th> + <th class="duration" title="The maximum amount of time that ingest has been held across all servers due to a lack of memory to store the records">Hold Time</th> + <th class="big-num" title="The Unix one minute load average. The average number of processes in the run queue over a one minute interval.">OS Load</th> + </tr> + </thead> + <tbody></tbody> + </table> + <br /><br /> + <table id="recoveryList" class="table table-bordered table-striped table-condensed"> + <caption><span class="table-caption">Log Recovery</span><br /> + <span class="table-subcaption">Some tablets were unloaded in an unsafe manner. Write-ahead logs are being + recovered.</span><br /> + </caption> + <thead> + <tr> <th>Server</th> <th>Log</th> - <th>Time</th> - <th>Progress</th> - </tr> - </thead> - <tbody></tbody> - </table> - </div> - </div> - <br/> - <#include "${tablesTemplate}"> + <th class="duration">Time</th> + <th class="percent">Progress</th> + </tr> + </thead> + <tbody></tbody> + </table> + <br /><br /> + <#include "${tablesTemplate}"> \ No newline at end of file diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/tables.ftl b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/tables.ftl index 80c79eef01..aa00b401e9 100644 --- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/tables.ftl +++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/tables.ftl @@ -81,15 +81,15 @@ */ function refresh() { <#if js??> - refreshManager(); + refreshManagerTables(); </#if> tableList.ajax.reload(null, false ); // user paging is not reset on reload } </script> - <div><h3>${tablesTitle}</h3></div> <div> <table id="tableList" class="table table-bordered table-striped table-condensed"> + <caption><span class="table-caption">${tablesTitle}</span><br /> <thead> <tr> <th>Table Name</th>