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 = '—';
+ 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 = '—';
+ if (data === null || data === undefined || data === 0) data =
'—';
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 '—';
+ }
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 '—';
+ }
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" />