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 828827af12 Centralize Monitor Server table definitons on backend 
(#6321)
828827af12 is described below

commit 828827af12fd698265b80f90338704bd25188199
Author: Dom G. <[email protected]>
AuthorDate: Mon Apr 20 14:50:45 2026 -0400

    Centralize Monitor Server table definitons on backend (#6321)
    
    * Centralize Monitor Server table definitons on backend so we can define a 
List<Metric> for each table and that will ultimately get translated to the 
columns in a table in the Monitor UI
---
 server/monitor/pom.xml                             |  24 ---
 .../apache/accumulo/monitor/next/Endpoints.java    |  18 +-
 .../accumulo/monitor/next/SystemInformation.java   |  37 ++--
 .../accumulo/monitor/next/views/ColumnJsGen.java   | 126 ------------
 .../accumulo/monitor/next/views/ServersView.java   | 229 +++++++++++++++++----
 .../accumulo/monitor/resources/js/compactors.js    |   9 +-
 .../accumulo/monitor/resources/js/functions.js     |  57 ++---
 .../org/apache/accumulo/monitor/resources/js/gc.js |  39 ++--
 .../accumulo/monitor/resources/js/manager.js       |  47 +++--
 .../monitor/resources/js/server_process_common.js  | 103 +++++----
 .../accumulo/monitor/resources/js/sservers.js      |   7 +-
 .../accumulo/monitor/resources/js/tservers.js      |   8 +-
 .../apache/accumulo/monitor/templates/default.ftl  |   1 -
 13 files changed, 366 insertions(+), 339 deletions(-)

diff --git a/server/monitor/pom.xml b/server/monitor/pom.xml
index 89a2597f9e..089502e40c 100644
--- a/server/monitor/pom.xml
+++ b/server/monitor/pom.xml
@@ -54,10 +54,6 @@
       <groupId>com.github.ben-manes.caffeine</groupId>
       <artifactId>caffeine</artifactId>
     </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
     <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
@@ -246,26 +242,6 @@
       </plugins>
     </pluginManagement>
     <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>metrics-javascript</id>
-            <goals>
-              <goal>java</goal>
-            </goals>
-            <phase>prepare-package</phase>
-            <configuration>
-              
<mainClass>org.apache.accumulo.monitor.next.views.ColumnJsGen</mainClass>
-              <classpathScope>compile</classpathScope>
-              <arguments>
-                
<argument>${project.build.directory}/classes/org/apache/accumulo/monitor/resources/js/columns.js</argument>
-              </arguments>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-resources-plugin</artifactId>
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/next/Endpoints.java 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/next/Endpoints.java
index a0b4971413..f570d1ecbf 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/next/Endpoints.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/next/Endpoints.java
@@ -32,6 +32,7 @@ import java.util.stream.Collectors;
 
 import jakarta.inject.Inject;
 import jakarta.servlet.http.HttpServletRequest;
+import jakarta.ws.rs.BadRequestException;
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.MatrixParam;
 import jakarta.ws.rs.NotFoundException;
@@ -66,11 +67,6 @@ public class Endpoints {
    */
   private static final String GROUP_PARAM_KEY = "group";
 
-  /**
-   * A {@code String} constant representing the supplied server type in path 
parameter.
-   */
-  private static final String SERVER_TYPE_KEY = "serverType";
-
   /**
    * A {@code String} constant representing the supplied tableId in path 
parameter.
    */
@@ -254,13 +250,15 @@ public class Endpoints {
   @GET
   @Path("servers/view")
   @Produces(MediaType.APPLICATION_JSON)
-  @Description("Returns a UI-ready view model for server processes. Add 
';serverType=<ServerId.Type>' to URL")
-  public ServersView getServerProcessView(@MatrixParam(SERVER_TYPE_KEY) 
ServerId.Type serverType) {
+  @Description("Returns a UI-ready table model for server process pages. Add 
';table=<ServersView.ServerTable>' to URL")
+  public ServersView getServerProcessView(@MatrixParam("table") 
ServersView.ServerTable table) {
+    if (table == null) {
+      throw new BadRequestException("A 'table' parameter is required");
+    }
     ServersView view =
-        
monitor.getInformationFetcher().getSummaryForEndpoint().getServerProcessView(serverType);
+        
monitor.getInformationFetcher().getSummaryForEndpoint().getServerProcessView(table);
     if (view == null) {
-      throw new NotFoundException(
-          "ServersView object for server type " + serverType.name() + " not 
found");
+      throw new NotFoundException("ServersView object for table " + 
table.name() + " not found");
     }
     return view;
   }
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/next/SystemInformation.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/next/SystemInformation.java
index 3c5c4f4475..db9e077f9e 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/next/SystemInformation.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/next/SystemInformation.java
@@ -413,8 +413,8 @@ public class SystemInformation {
   private final Set<String> configuredCompactionResourceGroups = 
ConcurrentHashMap.newKeySet();
 
   private final AtomicLong timestamp = new AtomicLong(0);
-  private EnumMap<ServerId.Type,Supplier<ServersView>> serverMetricsView =
-      new EnumMap<>(ServerId.Type.class);
+  private final EnumMap<ServersView.ServerTable,Supplier<ServersView>> 
serverMetricsView =
+      new EnumMap<>(ServersView.ServerTable.class);
   private DeploymentOverview deploymentOverview = new DeploymentOverview(0L, 
List.of());
   private final int rgLongRunningCompactionSize;
 
@@ -658,28 +658,28 @@ public class SystemInformation {
       switch (type) {
         case COMPACTOR:
           compactors.values().forEach(servers::addAll);
-          serverMetricsView.put(type, memoize(
-              () -> new ServersView(servers, problemHostCount, allMetrics, 
timestamp.get())));
+          cacheServerProcessView(ServersView.ServerTable.COMPACTORS, servers, 
problemHostCount);
           break;
         case GARBAGE_COLLECTOR:
           servers.add(gc.get());
-          serverMetricsView.put(type, memoize(
-              () -> new ServersView(servers, problemHostCount, allMetrics, 
timestamp.get())));
+          cacheServerProcessView(ServersView.ServerTable.GC_SUMMARY, servers, 
problemHostCount);
+          cacheServerProcessView(ServersView.ServerTable.GC_FILES, servers, 
problemHostCount);
+          cacheServerProcessView(ServersView.ServerTable.GC_WALS, servers, 
problemHostCount);
           break;
         case MANAGER:
           servers.addAll(managers);
-          serverMetricsView.put(type, memoize(
-              () -> new ServersView(servers, problemHostCount, allMetrics, 
timestamp.get())));
+          cacheServerProcessView(ServersView.ServerTable.MANAGERS, servers, 
problemHostCount);
+          cacheServerProcessView(ServersView.ServerTable.MANAGER_FATE, 
servers, problemHostCount);
+          cacheServerProcessView(ServersView.ServerTable.MANAGER_COMPACTIONS, 
servers,
+              problemHostCount);
           break;
         case SCAN_SERVER:
           sservers.values().forEach(servers::addAll);
-          serverMetricsView.put(type, memoize(
-              () -> new ServersView(servers, problemHostCount, allMetrics, 
timestamp.get())));
+          cacheServerProcessView(ServersView.ServerTable.SCAN_SERVERS, 
servers, problemHostCount);
           break;
         case TABLET_SERVER:
           tservers.values().forEach(servers::addAll);
-          serverMetricsView.put(type, memoize(
-              () -> new ServersView(servers, problemHostCount, allMetrics, 
timestamp.get())));
+          cacheServerProcessView(ServersView.ServerTable.TABLET_SERVERS, 
servers, problemHostCount);
           break;
         case MONITOR:
         default:
@@ -776,8 +776,17 @@ public class SystemInformation {
     return this.timestamp.get();
   }
 
-  public ServersView getServerProcessView(ServerId.Type type) {
-    Supplier<ServersView> view = this.serverMetricsView.get(type);
+  /**
+   * Cache a ServersView for the given table and set of servers.
+   */
+  private void cacheServerProcessView(ServersView.ServerTable table, 
Set<ServerId> servers,
+      long problemHostCount) {
+    serverMetricsView.put(table, memoize(() -> new ServersView(servers, 
problemHostCount,
+        allMetrics, timestamp.get(), ServersView.columnsFor(table))));
+  }
+
+  public ServersView getServerProcessView(ServersView.ServerTable table) {
+    Supplier<ServersView> view = this.serverMetricsView.get(table);
     if (view != null) {
       return view.get();
     }
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/next/views/ColumnJsGen.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/next/views/ColumnJsGen.java
deleted file mode 100644
index b2593dc6b4..0000000000
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/next/views/ColumnJsGen.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.monitor.next.views;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.accumulo.core.util.LazySingletons.GSON;
-import static org.apache.accumulo.monitor.next.views.ServersView.ADDR_COL_NAME;
-import static org.apache.accumulo.monitor.next.views.ServersView.RG_COL_NAME;
-import static org.apache.accumulo.monitor.next.views.ServersView.TIME_COL_NAME;
-import static org.apache.accumulo.monitor.next.views.ServersView.TYPE_COL_NAME;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
-
-import org.apache.accumulo.core.metrics.Metric;
-import org.apache.accumulo.core.metrics.Metric.MonitorCssClass;
-
-/**
- * This class generates a map of metric name to column information for the 
Monitor
- */
-public class ColumnJsGen {
-
-  public record ColumnInformation(String header, String description, String 
classes) {
-  };
-
-  private static void printHeader(PrintStream out) {
-    final String hdr = """
-        /*
-         * Licensed to the Apache Software Foundation (ASF) under one
-         * or more contributor license agreements.  See the NOTICE file
-         * distributed with this work for additional information
-         * regarding copyright ownership.  The ASF licenses this file
-         * to you under the Apache License, Version 2.0 (the
-         * "License"); you may not use this file except in compliance
-         * with the License.  You may obtain a copy of the License at
-         *
-         *   https://www.apache.org/licenses/LICENSE-2.0
-         *
-         * Unless required by applicable law or agreed to in writing,
-         * software distributed under the License is distributed on an
-         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-         * KIND, either express or implied.  See the License for the
-         * specific language governing permissions and limitations
-         * under the License.
-         */
-
-        "use strict";
-
-        const COLUMN_MAP = new Map([""";
-    out.println(hdr);
-  }
-
-  private static void printMetrics(PrintStream out) {
-
-    // Put in tree map to sort metrics by name in the output
-    Map<String,ColumnInformation> output = new TreeMap<>();
-    for (Metric m : Metric.values()) {
-      MonitorCssClass[] classes = m.getColumnClasses();
-      String css =
-          Arrays.stream(classes).map(c -> 
c.getCssClass()).collect(Collectors.joining(" "));
-      output.put(m.getName(),
-          new ColumnInformation(m.getColumnHeader(), m.getColumnDescription(), 
css));
-    }
-
-    // Add non-metric columns that are part of the ServersView
-    // object that is returned from the Monitor endpoint
-    output.put(ADDR_COL_NAME, new ColumnInformation(ADDR_COL_NAME, "Server 
Address", "firstcell"));
-    output.put(RG_COL_NAME,
-        new ColumnInformation(RG_COL_NAME, "Resource Group Name", 
"resource-group"));
-    output.put(TIME_COL_NAME,
-        new ColumnInformation(TIME_COL_NAME, "Last Contact Time", "duration"));
-    output.put(TYPE_COL_NAME,
-        new ColumnInformation(TYPE_COL_NAME, "Server Process Type", 
"server-type"));
-
-    final Set<String> keys = output.keySet();
-    final int numKeys = keys.size();
-    int counter = 0;
-    for (String key : keys) {
-      counter++;
-      out.println("  [\"%s\", %s]%s".formatted(key, 
GSON.get().toJson(output.get(key)),
-          counter == numKeys ? "" : ","));
-
-    }
-  }
-
-  private static void printFooter(PrintStream out) {
-    final String footer = """
-        ]);
-        """;
-    out.println(footer);
-  }
-
-  public static void main(String args[]) throws IOException {
-    if (args.length != 1) {
-      throw new IllegalArgumentException(
-          "Usage: " + ColumnJsGen.class.getName() + " <output_filename>");
-    }
-    try (var printStream = new PrintStream(args[0], UTF_8)) {
-      printHeader(printStream);
-      printMetrics(printStream);
-      printFooter(printStream);
-    }
-  }
-
-}
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/next/views/ServersView.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/next/views/ServersView.java
index 6b476c4ad3..4705ae33d8 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/next/views/ServersView.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/next/views/ServersView.java
@@ -19,16 +19,18 @@
 package org.apache.accumulo.monitor.next.views;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 import org.apache.accumulo.core.client.admin.servers.ServerId;
+import org.apache.accumulo.core.metrics.Metric;
+import org.apache.accumulo.core.metrics.Metric.MetricDocSection;
 import org.apache.accumulo.core.metrics.flatbuffers.FMetric;
 import org.apache.accumulo.core.metrics.flatbuffers.FTag;
 import org.apache.accumulo.core.process.thrift.MetricResponse;
@@ -48,6 +50,11 @@ import com.github.benmanes.caffeine.cache.Cache;
  * data    - an array of objects that can be used for the Data Table data 
definition
  * status  - overall status information, counts, warnings, etc.
  * </pre>
+ *
+ * Each server-process table is identified by {@link ServerTable}. The 
table-specific metric methods
+ * define the metrics for each table, {@link #columnsFor(ServerTable)} 
converts those metrics to
+ * column definitions. The frontend uses the returned column definitions to 
build the table headers
+ * and DataTables column configuration.
  */
 public class ServersView {
 
@@ -59,54 +66,96 @@ public class ServersView {
       String message) {
   }
 
-  public static final String TYPE_COL_NAME = "Server Type";
-  public static final String RG_COL_NAME = "Resource Group";
-  public static final String ADDR_COL_NAME = "Server Address";
-  public static final String TIME_COL_NAME = "Last Contact";
+  /**
+   * Definition of a column to be rendered in the UI
+   */
+  public record Column(String key, String label, String description, String 
uiClass) {
+  }
+
+  private record ServerMetricRow(ServerId server, MetricResponse response,
+      Map<String,Number> metrics) {
+  }
+
+  /**
+   * Server-process table identifiers accepted by /rest-v2/servers/view. These 
enum names are used
+   * directly as the frontend table parameter values.
+   */
+  public enum ServerTable {
+    COMPACTORS,
+    GC_SUMMARY,
+    GC_FILES,
+    GC_WALS,
+    MANAGERS,
+    MANAGER_FATE,
+    MANAGER_COMPACTIONS,
+    SCAN_SERVERS,
+    TABLET_SERVERS
+  }
 
   private static final String LEVEL_OK = "OK";
   private static final String LEVEL_WARN = "WARN";
 
+  public static final String RG_COL_KEY = "resourceGroup";
+  public static final String ADDR_COL_KEY = "serverAddress";
+  public static final String TIME_COL_KEY = "lastContact";
+
+  /**
+   * Common columns that are included in every ServersView table
+   */
+  private static final List<Column> COMMON_COLUMNS = List.of(
+      new Column(TIME_COL_KEY, "Last Contact",
+          "Time since the server last responded to the monitor", "duration"),
+      new Column(RG_COL_KEY, "Resource Group", "Resource Group", ""),
+      new Column(ADDR_COL_KEY, "Server Address", "Server address", ""));
+
   public final List<Map<String,Object>> data = new ArrayList<>();
-  public final Set<String> columns = new TreeSet<>();
+  public final List<Column> columns;
   public final Status status;
   public final long timestamp;
 
   public ServersView(final Set<ServerId> servers, final long 
problemServerCount,
-      final Cache<ServerId,MetricResponse> allMetrics, final long timestamp) {
+      final Cache<ServerId,MetricResponse> allMetrics, final long timestamp,
+      final List<Column> requestedColumns) {
 
     AtomicInteger serversMissingMetrics = new AtomicInteger(0);
-    servers.forEach(sid -> {
-      Map<String,Object> metrics = new TreeMap<>();
-
-      columns.add(TYPE_COL_NAME);
-      metrics.put(TYPE_COL_NAME, sid.getType().name());
-      columns.add(RG_COL_NAME);
-      metrics.put(RG_COL_NAME, sid.getResourceGroup().canonical());
-      columns.add(ADDR_COL_NAME);
-      metrics.put(ADDR_COL_NAME, sid.toHostPortString());
-
-      MetricResponse mr = allMetrics.getIfPresent(sid);
-      if (mr != null) {
-        // Don't use the timestamp for the last contact duration,
-        // use the current time.
-        columns.add(TIME_COL_NAME);
-        metrics.put(TIME_COL_NAME, System.currentTimeMillis() - 
mr.getTimestamp());
-
-        Map<String,Number> serverMetrics = metricValuesByName(mr);
-        for (Entry<String,Number> e : serverMetrics.entrySet()) {
-          columns.add(e.getKey());
-          metrics.put(e.getKey(), e.getValue());
-        }
-        data.add(metrics);
-      } else {
+    // Grab the current metrics for each server
+    List<ServerMetricRow> serverMetricRows = 
servers.stream().sorted().map(serverId -> {
+      MetricResponse metricResponse = allMetrics.getIfPresent(serverId);
+      boolean hasMetricData = hasMetricData(metricResponse);
+      Map<String,Number> serverMetrics =
+          hasMetricData ? metricValuesByName(metricResponse) : Map.of();
+
+      if (!hasMetricData) {
         serversMissingMetrics.incrementAndGet();
       }
+
+      return new ServerMetricRow(serverId, metricResponse, serverMetrics);
+    }).toList();
+
+    this.columns = requestedColumns;
+
+    serverMetricRows.forEach(serverMetricRow -> {
+      Map<String,Object> row = new LinkedHashMap<>();
+      for (Column col : columns) {
+        row.put(col.key(), valueForColumn(col.key(), serverMetricRow.server(),
+            serverMetricRow.response(), serverMetricRow.metrics()));
+      }
+      data.add(row);
     });
     status = buildStatus(servers.size(), problemServerCount, 
serversMissingMetrics.get());
     this.timestamp = timestamp;
   }
 
+  private static Object valueForColumn(String key, ServerId sid, 
MetricResponse mr,
+      Map<String,Number> serverMetrics) {
+    return switch (key) {
+      case TIME_COL_KEY -> mr == null ? null : System.currentTimeMillis() - 
mr.getTimestamp();
+      case RG_COL_KEY -> sid.getResourceGroup().canonical();
+      case ADDR_COL_KEY -> sid.toHostPortString();
+      default -> serverMetrics.get(key);
+    };
+  }
+
   private static Status buildStatus(int serverCount, long problemServerCount,
       int serversMissingMetrics) {
     final boolean hasServers = serverCount > 0;
@@ -131,6 +180,103 @@ public class ServersView {
         problemServerCount, serversMissingMetrics, LEVEL_WARN, message);
   }
 
+  private static boolean hasMetricData(MetricResponse mr) {
+    return mr != null && mr.getMetrics() != null && !mr.getMetrics().isEmpty();
+  }
+
+  /**
+   * Builds the final ordered columns for a table. First adds the common 
columns, then adds the
+   * table specific metrics.
+   */
+  public static List<Column> columnsFor(ServerTable table) {
+    List<Column> cols = new ArrayList<>(COMMON_COLUMNS);
+    
cols.addAll(metricsForTable(table).stream().map(ServersView::metricColumn).toList());
+    return cols;
+  }
+
+  private static List<Metric> metricsForTable(ServerTable table) {
+    return switch (table) {
+      case COMPACTORS -> compactorMetrics();
+      case GC_SUMMARY -> gcSummaryMetrics();
+      case GC_FILES -> gcFileMetrics();
+      case GC_WALS -> gcWalMetrics();
+      case MANAGERS -> managerMetrics();
+      case MANAGER_FATE -> managerFateMetrics();
+      case MANAGER_COMPACTIONS -> managerCompactionMetrics();
+      case SCAN_SERVERS -> scanServerMetrics();
+      case TABLET_SERVERS -> tabletServerMetrics();
+    };
+  }
+
+  /**
+   * The following helper methods are where the metrics included in each table 
are defined as well
+   * as their order.
+   */
+  private static List<Metric> compactorMetrics() {
+    return metricList(MetricDocSection.GENERAL_SERVER, 
MetricDocSection.COMPACTION,
+        MetricDocSection.COMPACTOR);
+  }
+
+  private static List<Metric> gcSummaryMetrics() {
+    return metricList(MetricDocSection.GENERAL_SERVER);
+  }
+
+  private static List<Metric> gcFileMetrics() {
+    return Arrays.stream(Metric.values()).filter(metric -> {
+      String name = metric.getName();
+      return metric.getDocSection() == MetricDocSection.GARBAGE_COLLECTION
+          && !name.startsWith("accumulo.gc.wal.");
+    }).toList();
+  }
+
+  private static List<Metric> gcWalMetrics() {
+    return Arrays.stream(Metric.values())
+        .filter(metric -> metric.getName().startsWith("accumulo.gc.wal."))
+        .collect(Collectors.toList());
+  }
+
+  private static List<Metric> managerMetrics() {
+    return metricList(MetricDocSection.GENERAL_SERVER, 
MetricDocSection.MANAGER);
+  }
+
+  private static List<Metric> managerFateMetrics() {
+    return metricList(MetricDocSection.FATE);
+  }
+
+  private static List<Metric> managerCompactionMetrics() {
+    return metricList(MetricDocSection.COMPACTION);
+  }
+
+  private static List<Metric> scanServerMetrics() {
+    return metricList(MetricDocSection.GENERAL_SERVER, 
MetricDocSection.SCAN_SERVER,
+        MetricDocSection.SCAN, MetricDocSection.BLOCK_CACHE);
+  }
+
+  private static List<Metric> tabletServerMetrics() {
+    return metricList(MetricDocSection.GENERAL_SERVER, 
MetricDocSection.TABLET_SERVER,
+        MetricDocSection.SCAN, MetricDocSection.COMPACTION, 
MetricDocSection.BLOCK_CACHE);
+  }
+
+  /**
+   * @return all the metrics for the given sections
+   */
+  private static List<Metric> metricList(MetricDocSection... sections) {
+    Set<MetricDocSection> requestedSections = Set.of(sections);
+    return Arrays.stream(Metric.values())
+        .filter(metric -> requestedSections.contains(metric.getDocSection()))
+        .collect(Collectors.toList());
+  }
+
+  /**
+   * @return a Column definition converted from the given Metric
+   */
+  private static Column metricColumn(Metric metric) {
+    String classes = Arrays.stream(metric.getColumnClasses())
+        .map(Metric.MonitorCssClass::getCssClass).collect(Collectors.joining(" 
"));
+    return new Column(metric.getName(), metric.getColumnHeader(), 
metric.getColumnDescription(),
+        classes);
+  }
+
   public static Map<String,Number> metricValuesByName(MetricResponse response) 
{
     var values = new HashMap<String,Number>();
     if (response == null || response.getMetrics() == null || 
response.getMetrics().isEmpty()) {
@@ -147,19 +293,16 @@ public class ServersView {
         values.compute(metric.name(), (k, v) -> {
           if (v == null) {
             return val;
+          } else if (v instanceof Integer i) {
+            return i + val.intValue();
+          } else if (v instanceof Long l) {
+            return l + val.longValue();
+          } else if (v instanceof Double d) {
+            return d + val.doubleValue();
           } else {
-            if (v instanceof Integer i) {
-              return i + val.intValue();
-            } else if (v instanceof Long l) {
-              return l + val.longValue();
-            } else if (v instanceof Double d) {
-              return d + val.doubleValue();
-            } else {
-              throw new RuntimeException("Unexpected value type: " + 
val.getClass());
-            }
+            throw new RuntimeException("Unexpected value type: " + 
val.getClass());
           }
         });
-        values.putIfAbsent(metric.name(), 
SystemInformation.getMetricValue(metric));
       }
     }
     return values;
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/compactors.js
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/compactors.js
index 11957b2e90..907f7935a4 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/compactors.js
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/compactors.js
@@ -25,18 +25,19 @@
 const htmlBanner = '#compactorsStatusBanner'
 const htmlBannerMessage = '#compactors-banner-message'
 const htmlTable = '#compactorsTable'
-const visibleColumnFilter = (col) => col != "Server Type";
 
 function refresh() {
-  refreshServerInformation(getCompactorsView, htmlTable, 
COMPACTOR_SERVER_PROCESS_VIEW, htmlBanner, htmlBannerMessage, 
visibleColumnFilter);
+  refreshServerInformation(getCompactorsView, htmlTable, 
COMPACTOR_SERVER_PROCESS_VIEW,
+    htmlBanner, htmlBannerMessage);
 }
 
 $(function () {
-  sessionStorage[SCAN_SERVER_PROCESS_VIEW] = JSON.stringify({
+  sessionStorage[COMPACTOR_SERVER_PROCESS_VIEW] = JSON.stringify({
     data: [],
     columns: [],
     status: null
   });
 
-  refreshServerInformation(getCompactorsView, htmlTable, 
COMPACTOR_SERVER_PROCESS_VIEW, htmlBanner, htmlBannerMessage, 
visibleColumnFilter);
+  refreshServerInformation(getCompactorsView, htmlTable, 
COMPACTOR_SERVER_PROCESS_VIEW,
+    htmlBanner, htmlBannerMessage);
 });
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 b8c0fbb34a..9b41856849 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
@@ -30,8 +30,12 @@ const REST_V2_PREFIX = contextPath + 'rest-v2';
 const MANAGER_GOAL_STATE_METRIC = 'accumulo.manager.goal.state';
 
 const COMPACTOR_SERVER_PROCESS_VIEW = 'compactorsView';
-const GC_SERVER_PROCESS_VIEW = 'gcView';
+const GC_SERVER_PROCESS_VIEW = 'gcSummaryView';
+const GC_FILE_SERVER_PROCESS_VIEW = 'gcFileView';
+const GC_WAL_SERVER_PROCESS_VIEW = 'gcWalView';
 const MANAGER_SERVER_PROCESS_VIEW = 'managerssView';
+const MANAGER_FATE_SERVER_PROCESS_VIEW = 'managersFateView';
+const MANAGER_COMPACTION_SERVER_PROCESS_VIEW = 'managersCompactionView';
 const SCAN_SERVER_PROCESS_VIEW = 'sserversView';
 const TABLET_SERVER_PROCESS_VIEW = 'tserversView';
 
@@ -677,44 +681,45 @@ function getDeployment() {
   return getJSONForTable(REST_V2_PREFIX + '/deployment', 'deployment');
 }
 
-/**
- * REST GET call for /servers/view;serverType=COMPACTOR,
- * stores it on a sessionStorage variable
- */
+function getServerProcessView(table, storageKey) {
+  var url = REST_V2_PREFIX + '/servers/view;table=' + table;
+  return getJSONForTable(url, storageKey);
+}
+
 function getCompactorsView() {
-  return getJSONForTable(REST_V2_PREFIX + 
'/servers/view;serverType=COMPACTOR', COMPACTOR_SERVER_PROCESS_VIEW);
+  return getServerProcessView('COMPACTORS', COMPACTOR_SERVER_PROCESS_VIEW);
 }
 
-/**
- * REST GET call for /servers/view;serverType=GARBAGE_COLLECTOR,
- * stores it on a sessionStorage variable
- */
 function getGcView() {
-  return getJSONForTable(REST_V2_PREFIX + 
'/servers/view;serverType=GARBAGE_COLLECTOR', GC_SERVER_PROCESS_VIEW);
+  return getServerProcessView('GC_SUMMARY', GC_SERVER_PROCESS_VIEW);
+}
+
+function getGcFileView() {
+  return getServerProcessView('GC_FILES', GC_FILE_SERVER_PROCESS_VIEW);
+}
+
+function getGcWalView() {
+  return getServerProcessView('GC_WALS', GC_WAL_SERVER_PROCESS_VIEW);
 }
 
-/**
- * REST GET call for /servers/view;serverType=MANAGER,
- * stores it on a sessionStorage variable
- */
 function getManagersView() {
-  return getJSONForTable(REST_V2_PREFIX + '/servers/view;serverType=MANAGER', 
MANAGER_SERVER_PROCESS_VIEW);
+  return getServerProcessView('MANAGERS', MANAGER_SERVER_PROCESS_VIEW);
+}
+
+function getManagersFateView() {
+  return getServerProcessView('MANAGER_FATE', 
MANAGER_FATE_SERVER_PROCESS_VIEW);
+}
+
+function getManagersCompactionView() {
+  return getServerProcessView('MANAGER_COMPACTIONS', 
MANAGER_COMPACTION_SERVER_PROCESS_VIEW);
 }
 
-/**
- * REST GET call for /servers/view;serverType=SCAN_SERVER,
- * stores it on a sessionStorage variable
- */
 function getSserversView() {
-  return getJSONForTable(REST_V2_PREFIX + 
'/servers/view;serverType=SCAN_SERVER', SCAN_SERVER_PROCESS_VIEW);
+  return getServerProcessView('SCAN_SERVERS', SCAN_SERVER_PROCESS_VIEW);
 }
 
-/**
- * REST GET call for /servers/view;serverType=TABLET_SERVER,
- * stores it on a sessionStorage variable
- */
 function getTserversView() {
-  return getJSONForTable(REST_V2_PREFIX + 
'/servers/view;serverType=TABLET_SERVER', TABLET_SERVER_PROCESS_VIEW);
+  return getServerProcessView('TABLET_SERVERS', TABLET_SERVER_PROCESS_VIEW);
 }
 
 
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/gc.js
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/gc.js
index 6c33007e80..caf70d956f 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/gc.js
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/gc.js
@@ -18,27 +18,24 @@
  */
 /* JSLint global definitions */
 /*global
-    $, GC_SERVER_PROCESS_VIEW, getGcView, refreshServerInformation
+    $, GC_SERVER_PROCESS_VIEW, GC_FILE_SERVER_PROCESS_VIEW, 
GC_WAL_SERVER_PROCESS_VIEW,
+    getGcView, getGcFileView, getGcWalView, refreshServerInformation
 */
 "use strict";
 
 const htmlBanner = '#gcStatusBanner'
 const htmlBannerMessage = '#gc-banner-message'
 const htmlTable = '#gc-server'
-const visibleColumnFilter = (col) => col != "Server Type" && 
!col.startsWith("accumulo.gc.");
-
 const fileHtmlTable = '#gc-file'
-const fileVisibleColumnFilter = (col) => col == "Last Contact" || col == 
"Resource Group" ||
-  col == "Server Address" || (col.startsWith("accumulo.gc.") && 
!col.startsWith("accumulo.gc.wal."));
-
 const walHtmlTable = '#gc-wal'
-const walVisibleColumnFilter = (col) => col == "Last Contact" || col == 
"Resource Group" ||
-  col == "Server Address" || col.startsWith("accumulo.gc.wal.");
 
 function refresh() {
-  refreshServerInformation(getGcView, htmlTable, GC_SERVER_PROCESS_VIEW, 
htmlBanner, htmlBannerMessage, visibleColumnFilter);
-  refreshServerInformation(getGcView, fileHtmlTable, GC_SERVER_PROCESS_VIEW, 
htmlBanner, htmlBannerMessage, fileVisibleColumnFilter);
-  refreshServerInformation(getGcView, walHtmlTable, GC_SERVER_PROCESS_VIEW, 
htmlBanner, htmlBannerMessage, walVisibleColumnFilter);
+  refreshServerInformation(getGcView, htmlTable, GC_SERVER_PROCESS_VIEW, 
htmlBanner,
+    htmlBannerMessage);
+  refreshServerInformation(getGcFileView, fileHtmlTable, 
GC_FILE_SERVER_PROCESS_VIEW, htmlBanner,
+    htmlBannerMessage);
+  refreshServerInformation(getGcWalView, walHtmlTable, 
GC_WAL_SERVER_PROCESS_VIEW, htmlBanner,
+    htmlBannerMessage);
 }
 
 $(function () {
@@ -48,7 +45,21 @@ $(function () {
     status: null
   });
 
-  refreshServerInformation(getGcView, htmlTable, GC_SERVER_PROCESS_VIEW, 
htmlBanner, htmlBannerMessage, visibleColumnFilter);
-  refreshServerInformation(getGcView, fileHtmlTable, GC_SERVER_PROCESS_VIEW, 
htmlBanner, htmlBannerMessage, fileVisibleColumnFilter);
-  refreshServerInformation(getGcView, walHtmlTable, GC_SERVER_PROCESS_VIEW, 
htmlBanner, htmlBannerMessage, walVisibleColumnFilter);
+  sessionStorage[GC_FILE_SERVER_PROCESS_VIEW] = JSON.stringify({
+    data: [],
+    columns: [],
+    status: null
+  });
+  sessionStorage[GC_WAL_SERVER_PROCESS_VIEW] = JSON.stringify({
+    data: [],
+    columns: [],
+    status: null
+  });
+
+  refreshServerInformation(getGcView, htmlTable, GC_SERVER_PROCESS_VIEW, 
htmlBanner,
+    htmlBannerMessage);
+  refreshServerInformation(getGcFileView, fileHtmlTable, 
GC_FILE_SERVER_PROCESS_VIEW, htmlBanner,
+    htmlBannerMessage);
+  refreshServerInformation(getGcWalView, walHtmlTable, 
GC_WAL_SERVER_PROCESS_VIEW, htmlBanner,
+    htmlBannerMessage);
 });
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 55d090f57f..18c2cc0f06 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
@@ -19,7 +19,9 @@
 /* JSLint global definitions */
 /*global
     $, sessionStorage, MANAGER_SERVER_PROCESS_VIEW, getManagersView, 
getStoredRows, getStoredStatus,
-    refreshTable, refreshBanner, showBannerError, 
getManagerGoalStateFromSession
+    MANAGER_FATE_SERVER_PROCESS_VIEW, MANAGER_COMPACTION_SERVER_PROCESS_VIEW, 
getManagersFateView,
+    getManagersCompactionView, refreshTable, refreshBanner, showBannerError,
+    getManagerGoalStateFromSession
 */
 "use strict";
 
@@ -29,16 +31,8 @@ const htmlBannerMessage = '#manager-banner-message'
 const managerStateBanner = '#managerStateBanner'
 const managerStateBannerMessage = '#manager-state-message'
 const htmlTable = '#managers'
-const visibleColumnFilter = (col) => col != "Server Type" && 
!col.startsWith("accumulo.compaction.") &&
-  !col.startsWith("accumulo.fate.");
-
 const fateHtmlTable = '#managers_fate'
-const fateVisibleColumnFilter = (col) => col == "Last Contact" || col == 
"Resource Group" ||
-  col == "Server Address" || col.startsWith("accumulo.fate.");
-
 const compactionHtmlTable = '#managers_compactions'
-const compactionVisibleColumnFilter = (col) => col == "Last Contact" || col == 
"Resource Group" ||
-  col == "Server Address" || col.startsWith("accumulo.compaction.");
 
 function updateManagerGoalStateBanner() {
   const goalState = getManagerGoalStateFromSession();
@@ -72,10 +66,10 @@ function refreshManagerBanners() {
 }
 
 function refresh() {
-  getManagersView().then(function () {
-    refreshTable(htmlTable, MANAGER_SERVER_PROCESS_VIEW, visibleColumnFilter);
-    refreshTable(fateHtmlTable, MANAGER_SERVER_PROCESS_VIEW, 
fateVisibleColumnFilter);
-    refreshTable(compactionHtmlTable, MANAGER_SERVER_PROCESS_VIEW, 
compactionVisibleColumnFilter);
+  $.when(getManagersView(), getManagersFateView(), 
getManagersCompactionView()).then(function () {
+    refreshTable(htmlTable, MANAGER_SERVER_PROCESS_VIEW);
+    refreshTable(fateHtmlTable, MANAGER_FATE_SERVER_PROCESS_VIEW);
+    refreshTable(compactionHtmlTable, MANAGER_COMPACTION_SERVER_PROCESS_VIEW);
     refreshManagerBanners();
     refreshBanner(htmlBanner, htmlBannerMessage, 
getStoredStatus(MANAGER_SERVER_PROCESS_VIEW));
   }).fail(function () {
@@ -84,13 +78,24 @@ function refresh() {
       columns: [],
       status: null
     });
-    refreshTable(htmlTable, MANAGER_SERVER_PROCESS_VIEW, visibleColumnFilter);
-    refreshTable(fateHtmlTable, MANAGER_SERVER_PROCESS_VIEW, 
fateVisibleColumnFilter);
-    refreshTable(compactionHtmlTable, MANAGER_SERVER_PROCESS_VIEW, 
compactionVisibleColumnFilter);
+    sessionStorage[MANAGER_FATE_SERVER_PROCESS_VIEW] = JSON.stringify({
+      data: [],
+      columns: [],
+      status: null
+    });
+    sessionStorage[MANAGER_COMPACTION_SERVER_PROCESS_VIEW] = JSON.stringify({
+      data: [],
+      columns: [],
+      status: null
+    });
+    refreshTable(htmlTable, MANAGER_SERVER_PROCESS_VIEW);
+    refreshTable(fateHtmlTable, MANAGER_FATE_SERVER_PROCESS_VIEW);
+    refreshTable(compactionHtmlTable, MANAGER_COMPACTION_SERVER_PROCESS_VIEW);
     $(runningBanner).show();
     $(htmlTable).hide();
     $(fateHtmlTable).hide();
     $(compactionHtmlTable).hide();
+    $(managerStateBanner).hide();
     showBannerError(htmlBanner, htmlBannerMessage);
   });
 }
@@ -101,6 +106,16 @@ $(function () {
     columns: [],
     status: null
   });
+  sessionStorage[MANAGER_FATE_SERVER_PROCESS_VIEW] = JSON.stringify({
+    data: [],
+    columns: [],
+    status: null
+  });
+  sessionStorage[MANAGER_COMPACTION_SERVER_PROCESS_VIEW] = JSON.stringify({
+    data: [],
+    columns: [],
+    status: null
+  });
 
   refresh();
 });
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/server_process_common.js
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/server_process_common.js
index 68eb3c7a9b..000f7a8a02 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/server_process_common.js
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/server_process_common.js
@@ -19,49 +19,53 @@
 /* JSLint global definitions */
 /*global
     $, sessionStorage, timeDuration, bigNumberForQuantity, bigNumberForSize, 
ajaxReloadTable,
-    renderActivityState, renderMemoryState, COLUMN_MAP
+    renderActivityState, renderMemoryState, dateFormat
 */
 "use strict";
 
 /**
  * This file contains methods used to display tables on the Monitor's
- * pages for server processes. The REST Endpoint 
/rest-v2/servers/view;serverType=<ServerId.Type>
+ * pages for server processes. The REST Endpoint 
/rest-v2/servers/view;table=<ServerTable>
  * returns a data structure that has the following format:
  * 
  * {
  *   "data": [
  *     {
- *       "colA", "valueA",
- *       "colB", "valueB"
+ *       "colA": "valueA",
+ *       "colB": "valueB"
  *     },
  *      {
- *       "colA", "valueA",
- *       "colB", "valueB"
+ *       "colA": "valueA",
+ *       "colB": "valueB"
  *      }
  *   ],
  *   "columns": [
- *     "colA",
- *     "colB"
+ *     {
+ *       "key": "colA",
+ *       "label": "Column A",
+ *       "description": "Description of Column A",
+ *       "uiClass": "big-num"
+ *     },
+ *     {
+ *       "key": "colB",
+ *       "label": "Column B",
+ *       "description": "Description of Column B",
+ *       "uiClass": ""
+ *     }
  *   ],
  *   "status": {
  *   },
  *   timestamp: long
  * }
  * 
- * The value for the 'columns' key is an array of strings, where each string 
is the name
- * of a column. The value for the 'data' key is an array of objects. Each 
object represents
- * a server and the fields in the object contain the fields specified in the 
'columns'
- * array and are in the same order.
+ * The value for the 'columns' key is an array of column definitions. The 
value for the
+ * 'data' key is an array of row objects keyed by the column 'key' values.
  * 
  * The 'columns' array is used to dynamically create table header rows in the 
html and
  * the 'data' object is directly consumed by the DataTable where each object 
in the 'data'
  * is a row in the table and each field in the object is a column.
- * 
- * Modify the exclusion list in AbstractServer to remove columns from being 
returned from
- * the AbstractServer.getMetrics RPC call. Be aware that other pages in the 
Monitor may
- * use this information, not just the server process pages. The entrypoint for 
using
- * the methods in this file is the refreshServerInformation method. To 
influence which columns
- * are displayed on the server process pages use the column filter in that 
method.
+ *
+ * The entrypoint for using the methods in this file is the 
refreshServerInformation method.
  */
 
 var dataTableRefs = new Map();
@@ -95,7 +99,6 @@ function getStoredRows(storageKey) {
   if (!Array.isArray(view.data)) {
     return [];
   }
-  console.debug('table data: ' + JSON.stringify(view.data));
   return view.data;
 }
 
@@ -109,25 +112,20 @@ function getStoredStatus(storageKey) {
 
 /**
  * This function is called as part of the DataTable initialization.
- * It retrieves the columns from the response and sets the columns
- * visibility based on the supplied filter. Setting the visiblity
- * to false will hide the column in the display even if the table
- * header HTML column exists. This allows us to create the table
- * header rows without supplying the filter.
+ * It retrieves the exact columns from the cached response and creates
+ * the DataTables column definitions from them.
  */
-function getDataTableCols(storageKey, visibleColumnFilter) {
+function getDataTableCols(storageKey) {
   var dataTableColumns = [];
   var storedColumns = getStoredColumns(storageKey);
-  var visibleColumns = storedColumns.filter(visibleColumnFilter);
   $.each(storedColumns, function (index, col) {
-    var v = visibleColumns.includes(col);
-    var colName = col.replaceAll(".", "\\.");
+    var colName = col.key.replaceAll(".", "\\.");
     dataTableColumns.push({
       data: colName,
-      visible: v
+      title: col.label,
+      className: col.uiClass || ''
     });
   });
-  console.debug('table columns: ' + JSON.stringify(dataTableColumns));
   return dataTableColumns;
 }
 
@@ -137,7 +135,7 @@ function getDataTableCols(storageKey, visibleColumnFilter) {
  * HTML elements from the columns, redefines the DataTable,
  * and executes an ajax method to load the data.
  */
-function refreshTable(table, storageKey, visibleColumnFilter) {
+function refreshTable(table, storageKey) {
 
   // Destroy the DataTable
   var dataTableRef = dataTableRefs.get(table);
@@ -156,27 +154,18 @@ function refreshTable(table, storageKey, 
visibleColumnFilter) {
 
   var storedColumns = getStoredColumns(storageKey);
   $.each(storedColumns, function (index, col) {
-    console.debug('Adding table header row for column: ' + 
JSON.stringify(col));
-    if (COLUMN_MAP.has(col)) {
-      var mapping = COLUMN_MAP.get(col);
-      var th = $(document.createElement("th"));
-      th.addClass(mapping.classes);
-      th.text(mapping.header);
-      th.attr("title", mapping.description);
-      theadRow.append(th);
-    } else {
-      var th = $(document.createElement("th"));
-      th.text(col);
-      th.attr("title", "Unmapped column");
-      theadRow.append(th);
-    }
+    var th = $(document.createElement("th"));
+    th.addClass(col.uiClass || '');
+    th.text(col.label);
+    th.attr("title", col.description || col.label);
+    theadRow.append(th);
   });
   thead.append(theadRow);
   htmlTableElement.append(thead);
   htmlTableElement.append($(document.createElement('tbody')));
 
   // Create the DataTable
-  dataTableRef = createDataTable(table, storageKey, visibleColumnFilter);
+  dataTableRef = createDataTable(table, storageKey);
   ajaxReloadTable(dataTableRef);
   dataTableRefs.set(table, dataTableRef);
 }
@@ -214,11 +203,10 @@ function showBannerError(banner, bannerMsg) {
  * storageKey - the session storage key for the data returned from the REST API
  * banner - reference to the HTML table that displays a banner
  * bannerMsg - reference to the HTML object that is the banner
- * visibleColumnFilter - filter to apply to columns to determine which are 
displayed
  */
-function refreshServerInformation(callback, table, storageKey, banner, 
bannerMsg, visibleColumnFilter) {
+function refreshServerInformation(callback, table, storageKey, banner, 
bannerMsg) {
   callback().then(function () {
-    refreshTable(table, storageKey, visibleColumnFilter);
+    refreshTable(table, storageKey);
     refreshBanner(banner, bannerMsg, getStoredStatus(storageKey));
   }).fail(function () {
     sessionStorage[storageKey] = JSON.stringify({
@@ -226,7 +214,7 @@ function refreshServerInformation(callback, table, 
storageKey, banner, bannerMsg
       columns: [],
       status: null
     });
-    refreshTable(table, storageKey, visibleColumnFilter);
+    refreshTable(table, storageKey);
     showBannerError(banner, bannerMsg);
   });
 }
@@ -237,7 +225,7 @@ function refreshServerInformation(callback, table, 
storageKey, banner, bannerMsg
  * certain columns should be rendered based on the columns
  * css class.
  */
-function createDataTable(table, storageKey, visibleColumnFilter) {
+function createDataTable(table, storageKey) {
   var dataTableRef = $(table).DataTable({
     "autoWidth": false,
     "ajax": function (data, callback) {
@@ -279,7 +267,8 @@ function createDataTable(table, storageKey, 
visibleColumnFilter) {
         "targets": "start-date",
         "render": function (data, type, row) {
           if (type === 'display') {
-            if (data === 0) data = 'Waiting';
+            if (data === null || data === undefined) data = '&mdash;';
+            else if (data === 0) data = 'Waiting';
             else if (data > 0) data = dateFormat(data);
             else data = 'Error';
           }
@@ -290,7 +279,7 @@ function createDataTable(table, storageKey, 
visibleColumnFilter) {
         "targets": "end-date",
         "render": function (data, type, row) {
           if (type === 'display') {
-            if (data === 0) data = '&mdash;';
+            if (data === null || data === undefined || data === 0) data = 
'&mdash;';
             else if (data > 0) data = dateFormat(data);
             else data = 'Error';
           }
@@ -301,6 +290,9 @@ function createDataTable(table, storageKey, 
visibleColumnFilter) {
         "targets": "duration",
         "render": function (data, type) {
           if (type === 'display') {
+            if (data === null || data === undefined) {
+              return '&mdash;';
+            }
             data = timeDuration(data);
           }
           return data;
@@ -310,6 +302,9 @@ function createDataTable(table, storageKey, 
visibleColumnFilter) {
         "targets": "percent",
         "render": function (data, type) {
           if (type === 'display') {
+            if (data === null || data === undefined) {
+              return '&mdash;';
+            }
             data = Math.round(data * 100) + '%';
           }
           return data;
@@ -324,7 +319,7 @@ function createDataTable(table, storageKey, 
visibleColumnFilter) {
         "render": renderMemoryState
       }
     ],
-    "columns": getDataTableCols(storageKey, visibleColumnFilter)
+    "columns": getDataTableCols(storageKey)
   });
   return dataTableRef;
 }
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/sservers.js
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/sservers.js
index eba0de1c13..7491874e6f 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/sservers.js
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/sservers.js
@@ -25,10 +25,10 @@
 const htmlBanner = '#sserversStatusBanner'
 const htmlBannerMessage = '#sservers-banner-message'
 const htmlTable = '#sservers'
-const visibleColumnFilter = (col) => col != "Server Type";
 
 function refresh() {
-  refreshServerInformation(getSserversView, htmlTable, 
SCAN_SERVER_PROCESS_VIEW, htmlBanner, htmlBannerMessage, visibleColumnFilter);
+  refreshServerInformation(getSserversView, htmlTable, 
SCAN_SERVER_PROCESS_VIEW, htmlBanner,
+    htmlBannerMessage);
 }
 
 $(function () {
@@ -38,5 +38,6 @@ $(function () {
     status: null
   });
 
-  refreshServerInformation(getSserversView, htmlTable, 
SCAN_SERVER_PROCESS_VIEW, htmlBanner, htmlBannerMessage, visibleColumnFilter);
+  refreshServerInformation(getSserversView, htmlTable, 
SCAN_SERVER_PROCESS_VIEW, htmlBanner,
+    htmlBannerMessage);
 });
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 bfb45dab69..d659a97f3c 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
@@ -26,8 +26,6 @@
 const htmlBanner = '#tserversStatusBanner'
 const htmlBannerMessage = '#tservers-banner-message'
 const htmlTable = '#tservers'
-const visibleColumnFilter = (col) => col != "Server Type";
-
 var tserversTable;
 var recoveryList = [];
 
@@ -97,7 +95,8 @@ function refreshTServersBanner() {
 function refresh() {
   refreshRecoveryList();
   refreshTServersBanner();
-  refreshServerInformation(getTserversView, htmlTable, 
TABLET_SERVER_PROCESS_VIEW, htmlBanner, htmlBannerMessage, visibleColumnFilter);
+  refreshServerInformation(getTserversView, htmlTable, 
TABLET_SERVER_PROCESS_VIEW, htmlBanner,
+    htmlBannerMessage);
 }
 
 $(function () {
@@ -110,5 +109,6 @@ $(function () {
     status: null
   });
 
-  refreshServerInformation(getTserversView, htmlTable, 
TABLET_SERVER_PROCESS_VIEW, htmlBanner, htmlBannerMessage, visibleColumnFilter);
+  refreshServerInformation(getTserversView, htmlTable, 
TABLET_SERVER_PROCESS_VIEW, htmlBanner,
+    htmlBannerMessage);
 });
diff --git 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/default.ftl
 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/default.ftl
index 1f26bfdc49..454294dedb 100644
--- 
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/default.ftl
+++ 
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/default.ftl
@@ -47,7 +47,6 @@
     <link rel="shortcut icon" type="image/jng" 
href="resources/images/favicon.png" />
     <script src="resources/js/global.js"></script>
     <script src="resources/js/functions.js"></script>
-    <script src="resources/js/columns.js"></script>
     <script src="resources/js/server_process_common.js"></script>
     <link rel="stylesheet" type="text/css" href="resources/css/screen.css" 
media="screen" />
 

Reply via email to