You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by do...@apache.org on 2022/06/03 17:42:15 UTC

[accumulo] branch main updated: Convert monitor tables in server.js to DataTables (#2725)

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 7f42c7d72a Convert monitor tables in server.js to DataTables (#2725)
7f42c7d72a is described below

commit 7f42c7d72ac8115a933b0e961c6f687c15360543
Author: Dom G <do...@gmail.com>
AuthorDate: Fri Jun 3 13:42:10 2022 -0400

    Convert monitor tables in server.js to DataTables (#2725)
    
    * Convert all tables in server.js to DataTables
    
    Co-authored-by: Christopher Tubbs <ct...@apache.org>
---
 .../apache/accumulo/monitor/resources/js/server.js | 340 ++++++++++++++++-----
 .../apache/accumulo/monitor/templates/server.ftl   | 118 ++-----
 2 files changed, 278 insertions(+), 180 deletions(-)

diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/server.js b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/server.js
index af539d0d00..54ade81ca5 100644
--- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/server.js
+++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/server.js
@@ -18,18 +18,16 @@
  */
 "use strict";
 
-var serv;
-var tabletResults;
+var detailTable, historyTable, currentTable, resultsTable;
+
 /**
  * Makes the REST calls, generates the tables with the new information
  */
 function refreshServer() {
-  getTServer(serv).then(function () {
-    refreshDetailTable();
-    refreshHistoryTable();
-    refreshCurrentTable();
-    refreshResultsTable();
-  });
+  ajaxReloadTable(detailTable);
+  ajaxReloadTable(historyTable);
+  ajaxReloadTable(currentTable);
+  ajaxReloadTable(resultsTable);
 }
 
 /**
@@ -40,91 +38,265 @@ function refresh() {
 }
 
 /**
- * Populates the server details table
- */
-function refreshDetailTable() {
-  var data = sessionStorage.server === undefined ? [] : JSON.parse(sessionStorage.server);
-  if (data.length === 0 || data.details === undefined) {
-    clearAllTableCells("tServerDetail");
-  } else {
-    $("#hostedTablets").text(bigNumberForQuantity(data.details.hostedTablets));
-    $("#entries").text(bigNumberForQuantity(data.details.entries));
-    $("#minors").text(bigNumberForQuantity(data.details.minors));
-    $("#majors").text(bigNumberForQuantity(data.details.majors));
-    $("#splits").text(bigNumberForQuantity(data.details.splits));
-  }
-}
-
-/**
- * Populates the All Time Tablet Operations table
+ * Initializes all of the DataTables for the given hostname
+ * 
+ * @param {String} serv the tserver hostname
  */
-function refreshHistoryTable() {
-  var data = sessionStorage.server === undefined ? [] : JSON.parse(sessionStorage.server);
+function initServerTables(serv) {
 
-  if (data.length === 0 || data.allTimeTabletResults === undefined) {
-    clearAllTableCells("opHistoryDetails");
-  } else {
-    var totalTimeSpent = 0;
-    $.each(data.allTimeTabletResults, function (key, val) {
-      totalTimeSpent += val.timeSpent;
-    });
+  const url = '/rest/tservers/' + serv;
+  console.debug('REST url used to fetch data for server.js DataTables: ' + url);
 
-    $.each(data.allTimeTabletResults, function (key, val) {
-      // use the first 5 characters of the operation for the jquery selector
-      var rowId = "#" + val.operation.slice(0, 5) + "Row";
-      console.log("Populating rowId " + rowId + " with " + val.operation + " data");
+  // Create a table for details on the current server
+  detailTable = $('#tServerDetail').DataTable({
+    "ajax": {
+      "url": url,
+      "dataSrc": function (data) {
+        // the data needs to be in an array to work with DataTables
+        var arr = [];
+        if (data.details === undefined) {
+          console.warn('the value of "details" is undefined');
+        } else {
+          arr = [data.details];
+        }
 
-      $(rowId).append("<td>" + val.operation + "</td>");
-      $(rowId).append("<td>" + bigNumberForQuantity(val.success) + "</td>");
-      $(rowId).append("<td>" + bigNumberForQuantity(val.failure) + "</td>");
+        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;
+      }
+    }],
+    "columns": [{
+        "data": "hostedTablets"
+      },
+      {
+        "data": "entries"
+      },
+      {
+        "data": "minors"
+      },
+      {
+        "data": "majors"
+      },
+      {
+        "data": "splits"
+      }
+    ]
+  });
 
-      appendDurationToRow(rowId, val.avgQueueTime);
-      appendDurationToRow(rowId, val.queueStdDev);
-      appendDurationToRow(rowId, val.avgTime);
-      appendDurationToRow(rowId, val.stdDev);
+  // Create a table for all time tablet operations
+  historyTable = $('#opHistoryDetails').DataTable({
+    "ajax": {
+      "url": url,
+      "dataSrc": "allTimeTabletResults"
+    },
+    "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": "duration",
+        "render": function (data, type) {
+          if (type === 'display') {
+            if (data === null) {
+              data = '-';
+            } else {
+              data = timeDuration(data * 1000.0);
+            }
+          }
+          return data;
+        }
+      }
+    ],
+    "columns": [{
+        "data": "operation"
+      },
+      {
+        "data": "success"
+      },
+      {
+        "data": "failure"
+      },
+      {
+        "data": "avgQueueTime"
+      },
+      {
+        "data": "queueStdDev"
+      },
+      {
+        "data": "avgTime"
+      },
+      {
+        "data": "stdDev"
+      },
+      {
+        "data": "timeSpent" // placeholder for percent column, replaced below
+      }
+    ],
+    // calculate and fill percent column each time table is drawn
+    "drawCallback": function () {
+      var totalTime = 0;
+      var api = this.api();
 
-      var percent = Math.floor((val.timeSpent / totalTimeSpent) * 100);
-      var progressBarCell = '<td><div class="progress"><div class="progress-bar"' +
-        ' role="progressbar" style="min-width: 2em; width:' + percent + '%;">' +
-        percent + '%</div></div></td>';
-      console.log("Time spent percent = " + val.timeSpent + "/" + totalTimeSpent + " " + percent);
+      // calculate total duration of all tablet operations
+      api.rows().every(function () {
+        totalTime += this.data().timeSpent;
+      });
 
-      $(rowId).append(progressBarCell);
-    });
-  }
-}
+      const percentColumnIndex = 7;
+      api.rows().every(function (rowIdx) {
+        // calculate the percentage of time taken for each row (each tablet op)
+        var currentPercent = (this.data().timeSpent / totalTime) * 100;
+        currentPercent = Math.round(currentPercent);
+        if (isNaN(currentPercent)) {
+          currentPercent = 0;
+        }
+        // insert the percentage bar into the current row and percent column
+        var newData = `<div class="progress"><div class="progress-bar" role="progressbar" style="min-width: 2em; width:${currentPercent}%;">${currentPercent}%</div></div>`
+        api.cell(rowIdx, percentColumnIndex).data(newData);
+      });
+    }
+  });
 
-/**
- * Populates the current tablet operations results table
- */
-function refreshCurrentTable() {
-  var data = sessionStorage.server === undefined ? [] : JSON.parse(sessionStorage.server);
+  // Create a table for tablet operations on the current server
+  currentTable = $('#currentTabletOps').DataTable({
+    "ajax": {
+      "url": url,
+      "dataSrc": function (data) {
+        // the data needs to be in an array to work with DataTables
+        var arr = [];
+        if (data.currentTabletOperationResults === undefined) {
+          console.warn('the value of "currentTabletOperationResults" is undefined');
+        } else {
+          arr = [data.currentTabletOperationResults];
+        }
 
-  if (data.length === 0 || data.currentTabletOperationResults === undefined) {
-    clearAllTableCells("currentTabletOps");
-  } else {
-    var current = data.currentTabletOperationResults;
-    $("#currentMinorAvg").html(timeDuration(current.currentMinorAvg * 1000.0));
-    $("#currentMinorStdDev").html(timeDuration(current.currentMinorStdDev * 1000.0));
-    $("#currentMajorAvg").html(timeDuration(current.currentMajorAvg * 1000.0));
-    $("#currentMajorStdDev").html(timeDuration(current.currentMajorStdDev * 1000.0));
-  }
-}
+        return arr;
+      }
+    },
+    "stateSave": true,
+    "searching": false,
+    "paging": false,
+    "info": false,
+    "columnDefs": [{
+      "targets": "duration",
+      "render": function (data, type) {
+        if (type === 'display') {
+          data = timeDuration(data * 1000.0);
+        }
+        return data;
+      }
+    }],
+    "columns": [{
+        "data": "currentMinorAvg"
+      },
+      {
+        "data": "currentMinorStdDev"
+      },
+      {
+        "data": "currentMajorAvg"
+      },
+      {
+        "data": "currentMajorStdDev"
+      }
+    ]
+  });
 
-/**
- * Generates the server results table
- */
-function refreshResultsTable() {
-  tabletResults.ajax.reload(null, false); // user paging is not reset on reload
-}
+  // Create a table for detailed tablet operations
+  resultsTable = $('#perTabletResults').DataTable({
+    "ajax": {
+      "url": url,
+      "dataSrc": "currentOperations"
+    },
+    "stateSave": true,
+    "dom": 't<"align-left"l>p',
+    "columnDefs": [{
+        "targets": "big-num",
+        "render": function (data, type) {
+          if (type === 'display') {
+            data = bigNumberForQuantity(data);
+          }
+          return data;
+        }
+      },
+      {
+        "targets": "duration",
+        "render": function (data, type) {
+          if (type === 'display') {
+            data = timeDuration(data);
+          }
+          return data;
+        }
+      }
+    ],
+    "columns": [{
+        "data": "name",
+        "type": "html",
+        "render": function (data, type, row) {
+          if (type === 'display') {
+            data = `<a href="/tables/${row.tableID}">${data}</a>`;
+          }
+          return data;
+        }
+      },
+      {
+        "data": "tablet",
+        "type": "html",
+        "render": function (data, type) {
+          if (type === 'display') {
+            data = `<code>${data}</code>`;
+          }
+          return data;
+        }
+      },
+      {
+        "data": "entries"
+      },
+      {
+        "data": "ingest"
+      },
+      {
+        "data": "query"
+      },
+      {
+        "data": "minorAvg"
+      },
+      {
+        "data": "minorStdDev"
+      },
+      {
+        "data": "minorAvgES"
+      },
+      {
+        "data": "majorAvg"
+      },
+      {
+        "data": "majorStdDev"
+      },
+      {
+        "data": "majorAvgES"
+      }
+    ]
+  });
 
-/*
- * Appends a table cell containing value to the rowId, if value is not null
- */
-function appendDurationToRow(rowId, value) {
-  let v = EMPTY_CELL;
-  if (value != null) {
-    v = "<td>" + timeDuration(value * 1000.0) + "</td>";
-  }
-  $(rowId).append(v);
+  refreshServer();
 }
diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/server.ftl b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/server.ftl
index fc16786ee6..3d9428ed39 100644
--- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/server.ftl
+++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/server.ftl
@@ -19,65 +19,10 @@
 
 -->
       <script>
-      /**
-       * Creates a DataTable for tablet details.  The "dom" option tells DataTables to only
-       * show the table(t), length selector(l) aligned to the left and pagination(p).
-       */
-      $(document).ready(function() {
-        // Global constant for the page
-        serv = '${server}';
-
-        // Create a table for tserver list
-        tabletResults = $('#perTabletResults').DataTable({
-          "ajax": {
-            "url": '/rest/tservers/${server}',
-            "dataSrc": "currentOperations"
-          },
-          "stateSave": true,
-          "dom": 't<"align-left"l>p',
-          "columnDefs": [
-              { "targets": "big-num",
-                "render": function ( data, type, row ) {
-                  if(type === 'display') data = bigNumberForQuantity(data);
-                  return data;
-                }
-              },
-              { "targets": "duration",
-                "render": function ( data, type, row ) {
-                  if(type === 'display') data = timeDuration(data);
-                  return data;
-                }
-              }
-            ],
-          "columns": [
-            { "data": "name",
-              "type": "html",
-              "render": function ( data, type, row, meta ) {
-                if(type === 'display') data = '<a href="/tables/' + row.tableID + '">' + data + '</a>';
-                return data;
-              }
-            },
-            { "data": "tablet",
-              "type": "html",
-              "render": function ( data, type, row, meta ) {
-                if(type === 'display') data = '<code>' + data + '</code>';
-                return data;
-              }
-            },
-            { "data": "entries" },
-            { "data": "ingest" },
-            { "data": "query" },
-            { "data": "minorAvg" },
-            { "data": "minorStdDev" },
-            { "data": "minorAvgES" },
-            { "data": "majorAvg" },
-            { "data": "majorStdDev" },
-            { "data": "majorAvgES" }
-          ]
+        $(document).ready(function() {
+          // initialize DataTables
+          initServerTables('${server}');
         });
-        refreshServer();
-      });
-
       </script>
       <div class="row">
         <div class="col-xs-12">
@@ -90,22 +35,14 @@
             <caption><span class="table-caption">${server}</span></caption>
             <thead>
               <tr>
-                <th class="firstcell">Hosted&nbsp;Tablets&nbsp;</th>
-                <th>Entries&nbsp;</th>
-                <th>Minor&nbsp;Compacting&nbsp;</th>
-                <th>Major&nbsp;Compacting&nbsp;</th>
-                <th>Splitting&nbsp;</th>
+                <th class="big-num">Hosted&nbsp;Tablets&nbsp;</th>
+                <th class="big-num">Entries&nbsp;</th>
+                <th class="big-num">Minor&nbsp;Compacting&nbsp;</th>
+                <th class="big-num">Major&nbsp;Compacting&nbsp;</th>
+                <th class="big-num">Splitting&nbsp;</th>
               </tr>
             </thead>
-            <tbody>
-                <tr>
-                    <td id="hostedTablets"></td>
-                    <td id="entries"></td>
-                    <td id="minors"></td>
-                    <td id="majors"></td>
-                    <td id="splits"></td>
-                </tr>
-            </tbody>
+            <tbody></tbody>
           </table>
         </div>
       </div>
@@ -115,21 +52,17 @@
             <caption><span class="table-caption">All-Time&nbsp;Tablet&nbsp;Operation&nbsp;Results</span></caption>
             <thead>
               <tr>
-                <th class="firstcell">Operation&nbsp;</th>
-                <th>Success&nbsp;</th>
-                <th>Failure&nbsp;</th>
-                <th>Average<br/>Queue&nbsp;Time&nbsp;</th>
-                <th>Std.&nbsp;Dev.<br/>Queue&nbsp;Time&nbsp;</th>
-                <th>Average<br/>Time&nbsp;</th>
-                <th>Std.&nbsp;Dev.<br/>Time&nbsp;</th>
+                <th>Operation&nbsp;</th>
+                <th class="big-num">Success&nbsp;</th>
+                <th class="big-num">Failure&nbsp;</th>
+                <th class="duration">Average<br/>Queue&nbsp;Time&nbsp;</th>
+                <th class="duration">Std.&nbsp;Dev.<br/>Queue&nbsp;Time&nbsp;</th>
+                <th class="duration">Average<br/>Time&nbsp;</th>
+                <th class="duration">Std.&nbsp;Dev.<br/>Time&nbsp;</th>
                 <th>Percentage&nbsp;Time&nbsp;Spent&nbsp;</th>
               </tr>
             </thead>
-            <tbody>
-              <tr id="MinorRow"></tr>
-              <tr id="MajorRow"></tr>
-              <tr id="SplitRow"></tr>
-            </tbody>
+            <tbody></tbody>
           </table>
         </div>
       </div>
@@ -139,20 +72,13 @@
             <caption><span class="table-caption">Current&nbsp;Tablet&nbsp;Operation&nbsp;Results</span></caption>
             <thead>
               <tr>
-                <th class="firstcell">Minor&nbsp;Average&nbsp;</th>
-                <th>Minor&nbsp;Std&nbsp;Dev&nbsp;</th>
-                <th>Major&nbsp;Avg&nbsp;</th>
-                <th>Major&nbsp;Std&nbsp;Dev&nbsp;</th>
+                <th class="duration">Minor&nbsp;Average&nbsp;</th>
+                <th class="duration">Minor&nbsp;Std&nbsp;Dev&nbsp;</th>
+                <th class="duration">Major&nbsp;Avg&nbsp;</th>
+                <th class="duration">Major&nbsp;Std&nbsp;Dev&nbsp;</th>
               </tr>
             </thead>
-            <tbody>
-                <tr>
-                  <td id="currentMinorAvg"></td>
-                  <td id="currentMinorStdDev"></td>
-                  <td id="currentMajorAvg"></td>
-                  <td id="currentMajorStdDev"></td>
-                </tr>
-            </tbody>
+            <tbody></tbody>
           </table>
         </div>
       </div>