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 5da24b970f Add Tserver Distribution table to the per table monitor
page (#6367)
5da24b970f is described below
commit 5da24b970fcb22922cdcd28d922a0bf03ad0d95f
Author: Dom G. <[email protected]>
AuthorDate: Thu May 14 21:06:48 2026 -0400
Add Tserver Distribution table to the per table monitor page (#6367)
* Add Tserver Summary table to the per table monitor page
---
.../apache/accumulo/monitor/resources/js/table.js | 155 +++++++++++++++++++--
.../apache/accumulo/monitor/templates/table.ftl | 19 +++
2 files changed, 165 insertions(+), 9 deletions(-)
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 0dd150c89e..4f4c9e8979 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,67 @@ function initTabletsTable(tableId) {
});
}
+/**
+ * Initializes the tablet server rollup table.
+ */
+function initTabletServersTable() {
+ tabletServersTable = $('#tabletServersList').DataTable({
+ "stateSave": true,
+ "colReorder": true,
+ "searching": false,
+ "paging": false,
+ "info": false,
+ "order": [
+ // Sort by tablet count to surface uneven tablet distribution.
+ [1, '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": "tabletServer",
+ "title": "Tablet Server"
+ },
+ {
+ "data": "tabletCount",
+ "title": "Tablet Count"
+ },
+ {
+ "data": "estimatedEntries",
+ "title": "Estimated Entries"
+ },
+ {
+ "data": "estimatedSize",
+ "title": "Estimated Size"
+ },
+ {
+ "data": "numFiles",
+ "title": "Files"
+ },
+ {
+ "data": "numWalLogs",
+ "title": "WALs"
+ }
+ ]
+ });
+}
+
/**
* Initialize the table
*
@@ -106,6 +241,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 +330,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 5c034e432e..2bd7e2224f 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 @@
</div>
</div>
<br><br>
+ <div class="row">
+ <div class="col-xs-12">
+ <table id="tabletServersList" class="table caption-top
table-bordered table-striped table-condensed">
+ <caption><span class="table-caption">Tablet Distribution
Summary</span></caption>
+ <thead>
+ <tr>
+ <th>Tablet Server</th>
+ <th class="big-num">Tablet Count</th>
+ <th class="big-num">Estimated Entries</th>
+ <th class="big-size">Estimated Size</th>
+ <th class="big-num">Files</th>
+ <th class="big-num">WALs</th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ </div>
+ <br><br>
<!-- Section for tablets details DataTable -->
<div class="row">
<div class="col-xs-12">