diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/table.js b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/table.js index 0dd150c89e9..198ea151328 100644 --- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/table.js +++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/table.js @@ -19,13 +19,75 @@ "use strict"; var tableServersTable; +var tabletServersTable; var tabletsTable; +var tabletsUrl; /** * Makes the REST calls, generates the tables with the new information */ function refreshTable() { - ajaxReloadTable(tableServersTable); + if (tableServersTable) { + ajaxReloadTable(tableServersTable); + } + if (tabletsUrl && tabletServersTable && tabletsTable) { + refreshTabletTables(); + } +} + +/** + * @returns {String} the tablet server host and port parsed from the given location string, or "UNASSIGNED" if unavailable + */ +function tabletServerFromLocation(location) { + if (!location) { + return 'UNASSIGNED'; + } + + if (location.startsWith('CURRENT:')) { + return location.substring('CURRENT:'.length); + } + + if (location.startsWith('FUTURE:')) { + return location.substring('FUTURE:'.length); + } + + const separator = location.indexOf(':'); + if (separator < 0 || separator + 1 >= location.length) { + return location; + } + + return location.substring(separator + 1); +} + +/** + * Roll up per-tablet counts by tablet server. + */ +function summarizeTabletsByServer(tablets) { + const summaries = new Map(); + + tablets.forEach(function (tablet) { + const server = tabletServerFromLocation(tablet.location); + let summary = summaries.get(server); + if (summary === undefined) { + summary = { + tabletServer: server, + tabletCount: 0, + estimatedEntries: 0, + estimatedSize: 0, + numFiles: 0, + numWalLogs: 0 + }; + summaries.set(server, summary); + } + + summary.tabletCount += 1; + summary.estimatedEntries += tablet.estimatedEntries ?? 0; + summary.estimatedSize += tablet.estimatedSize ?? 0; + summary.numFiles += tablet.numFiles ?? 0; + summary.numWalLogs += tablet.numWalLogs ?? 0; + }); + + return Array.from(summaries.values()); } /** @@ -38,15 +100,27 @@ function refresh() { /** * Makes the REST call to fetch tablet details and render them. */ -function initTabletsTable(tableId) { - var tabletsUrl = contextPath + 'rest-v2/tables/' + tableId + '/tablets'; +function refreshTabletTables() { console.debug('Fetching tablets info from: ' + tabletsUrl); + $.getJSON(tabletsUrl, function (data) { + var tablets = Array.isArray(data) ? data : []; + + tabletServersTable.clear(); + tabletServersTable.rows.add(summarizeTabletsByServer(tablets)); + tabletServersTable.draw(false); + + tabletsTable.clear(); + tabletsTable.rows.add(tablets); + tabletsTable.draw(false); + }); +} + +/** + * Initializes the tablet details table. + */ +function initTabletsTable() { tabletsTable = $('#tabletsList').DataTable({ - "ajax": { - "url": tabletsUrl, - "dataSrc": "" - }, "stateSave": true, "columnDefs": [{ "targets": "big-num", @@ -99,6 +173,65 @@ function initTabletsTable(tableId) { }); } +/** + * Initializes the tablet server rollup table. + */ +function initTabletServersTable() { + tabletServersTable = $('#tabletServersList').DataTable({ + "stateSave": true, + "searching": false, + "paging": false, + "info": false, + "order": [ + [0, 'asc'] + ], + "columnDefs": [{ + "targets": "big-num", + "render": function (data, type) { + if (type === 'display') { + data = bigNumberForQuantity(data); + } + return data; + } + }, + { + "targets": "big-size", + "render": function (data, type) { + if (type === 'display') { + data = bigNumberForSize(data); + } + return data; + } + } + ], + "columns": [{ + "data": "tabletCount", + "title": "Tablet Count" + }, + { + "data": "tabletServer", + "title": "Tablet Server" + }, + { + "data": "estimatedEntries", + "title": "Estimated Entries" + }, + { + "data": "estimatedSize", + "title": "Estimated Size" + }, + { + "data": "numFiles", + "title": "Files" + }, + { + "data": "numWalLogs", + "title": "WALs" + } + ] + }); +} + /** * Initialize the table * @@ -106,6 +239,7 @@ function initTabletsTable(tableId) { */ function initTableServerTable(tableId) { const url = contextPath + 'rest-v2/tables/' + tableId; + tabletsUrl = contextPath + 'rest-v2/tables/' + tableId + '/tablets'; console.debug('REST url used to fetch summary data: ' + url); tableServersTable = $('#participatingTServers').DataTable({ @@ -194,6 +328,7 @@ function initTableServerTable(tableId) { ] }); - refreshTable(); - initTabletsTable(tableId); + initTabletServersTable(); + initTabletsTable(); + refreshTabletTables(); } diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/table.ftl b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/table.ftl index 5c034e432e0..458e5989382 100644 --- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/table.ftl +++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/table.ftl @@ -57,6 +57,25 @@

+
+
+ + + + + + + + + + + + + +
Tablet Distribution Summary
Tablet CountTablet ServerEstimated EntriesEstimated SizeFilesWALs
+
+
+