This is an automated email from the ASF dual-hosted git repository.
dlmarion 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 1965cc3105 Created Compaction Overview page (#6328)
1965cc3105 is described below
commit 1965cc31055e06d1ef1005c37d7959626f5069b7
Author: Dave Marion <[email protected]>
AuthorDate: Mon Apr 27 16:52:16 2026 -0400
Created Compaction Overview page (#6328)
This commit changes the labels in the Monitor Activity Menu a bit
and adds a new Compaction Overview page. The coordinator activity
table was moved from the Manager page to this new page, along with
tables for queue activity, running compactions by table and group.
Co-authored-by: Dom G. <[email protected]>
---
.../apache/accumulo/monitor/next/Endpoints.java | 18 +++
.../accumulo/monitor/next/SystemInformation.java | 126 +++++++++++++++++--
.../accumulo/monitor/next/views/ServersView.java | 91 +++++++++-----
.../org/apache/accumulo/monitor/view/WebViews.java | 17 +++
.../accumulo/monitor/resources/js/coordinator.js | 134 +++++++++++++++++++++
.../accumulo/monitor/resources/js/functions.js | 24 ++++
.../accumulo/monitor/resources/js/manager.js | 18 +--
.../accumulo/monitor/templates/coordinator.ftl | 54 +++++++++
.../apache/accumulo/monitor/templates/manager.ftl | 5 -
.../apache/accumulo/monitor/templates/navbar.ftl | 5 +-
10 files changed, 425 insertions(+), 67 deletions(-)
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 f570d1ecbf..6346f22d10 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
@@ -51,6 +51,8 @@ import org.apache.accumulo.core.process.thrift.MetricResponse;
import org.apache.accumulo.core.util.compaction.RunningCompactionInfo;
import org.apache.accumulo.monitor.Monitor;
import org.apache.accumulo.monitor.next.InformationFetcher.InstanceSummary;
+import
org.apache.accumulo.monitor.next.SystemInformation.CompactionGroupSummary;
+import
org.apache.accumulo.monitor.next.SystemInformation.CompactionTableSummary;
import org.apache.accumulo.monitor.next.SystemInformation.TableSummary;
import
org.apache.accumulo.monitor.next.SystemInformation.TimeOrderedRunningCompactionSet;
import org.apache.accumulo.monitor.next.deployment.DeploymentOverview;
@@ -321,6 +323,22 @@ public class Endpoints {
.collect(Collectors.toList());
}
+ @GET
+ @Path("compactions/running/group")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Description("Returns number of running major compactions per group")
+ public List<CompactionGroupSummary> getRunningCompactionsPerGroup() {
+ return
monitor.getInformationFetcher().getSummaryForEndpoint().getRunningCompactionsPerGroup();
+ }
+
+ @GET
+ @Path("compactions/running/table")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Description("Returns number of running major compactions per table")
+ public List<CompactionTableSummary> getRunningCompactionsPerTable() {
+ return
monitor.getInformationFetcher().getSummaryForEndpoint().getRunningCompactionsPerTable();
+ }
+
@GET
@Path("compactions/running/{" + GROUP_PARAM_KEY + "}")
@Produces(MediaType.APPLICATION_JSON)
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 2bd4444e42..33493e3265 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
@@ -19,6 +19,7 @@
package org.apache.accumulo.monitor.next;
import static com.google.common.base.Suppliers.memoize;
+import static org.apache.accumulo.core.metrics.MetricsInfo.QUEUE_TAG_KEY;
import java.nio.ByteBuffer;
import java.time.Duration;
@@ -26,6 +27,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -43,6 +45,7 @@ import java.util.function.Supplier;
import java.util.stream.Stream;
import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.TabletAvailability;
import org.apache.accumulo.core.client.admin.TabletInformation;
import org.apache.accumulo.core.client.admin.TabletMergeabilityInfo;
@@ -57,7 +60,6 @@ import org.apache.accumulo.core.dataImpl.TabletIdImpl;
import org.apache.accumulo.core.metadata.SystemTables;
import org.apache.accumulo.core.metadata.TabletState;
import org.apache.accumulo.core.metrics.Metric;
-import org.apache.accumulo.core.metrics.MetricsInfo;
import org.apache.accumulo.core.metrics.flatbuffers.FMetric;
import org.apache.accumulo.core.metrics.flatbuffers.FTag;
import org.apache.accumulo.core.process.thrift.MetricResponse;
@@ -65,6 +67,8 @@ import
org.apache.accumulo.core.spi.balancer.TableLoadBalancer;
import org.apache.accumulo.core.util.compaction.RunningCompactionInfo;
import org.apache.accumulo.monitor.next.deployment.DeploymentOverview;
import org.apache.accumulo.monitor.next.views.ServersView;
+import org.apache.accumulo.monitor.next.views.ServersView.Column;
+import org.apache.accumulo.monitor.next.views.ServersView.ColumnFactory;
import org.apache.accumulo.server.ServerContext;
import org.apache.accumulo.server.conf.TableConfiguration;
import org.apache.accumulo.server.metrics.MetricResponseWrapper;
@@ -352,6 +356,12 @@ public class SystemInformation {
}
+ public record CompactionTableSummary(String tableId, String tableName, long
running) {
+ }
+
+ public record CompactionGroupSummary(String groupId, long running) {
+ }
+
private static final Logger LOG =
LoggerFactory.getLogger(SystemInformation.class);
private final DistributionStatisticConfig DSC =
@@ -401,6 +411,9 @@ public class SystemInformation {
protected final Map<TableId,LongAdder> runningCompactionsPerTable = new
ConcurrentHashMap<>();
protected final Map<String,LongAdder> runningCompactionsPerGroup = new
ConcurrentHashMap<>();
+ private final List<CompactionTableSummary> tableCompactions = new
ArrayList<>();
+ private final List<CompactionGroupSummary> groupCompactions = new
ArrayList<>();
+
// Table Information
private final Map<TableId,TableSummary> tables = new ConcurrentHashMap<>();
private final Map<TableId,List<TabletInformation>> tablets = new
ConcurrentHashMap<>();
@@ -449,6 +462,8 @@ public class SystemInformation {
suggestions.clear();
runningCompactionsPerGroup.clear();
runningCompactionsPerTable.clear();
+ tableCompactions.clear();
+ groupCompactions.clear();
configuredCompactionResourceGroups.clear();
serverMetricsView.clear();
}
@@ -490,20 +505,80 @@ public class SystemInformation {
}
- private void createCompactionSummary(MetricResponse response) {
- if (response.getMetrics() != null) {
- for (final ByteBuffer binary : response.getMetrics()) {
- FMetric fm = FMetric.getRootAsFMetric(binary);
- for (int i = 0; i < fm.tagsLength(); i++) {
- FTag t = fm.tags(i);
- if (t.key().equals(MetricsInfo.QUEUE_TAG_KEY)) {
- queueMetrics
- .computeIfAbsent(t.value(), (k) ->
Collections.synchronizedList(new ArrayList<>()))
- .add(fm);
+ private ServersView createCompactionQueueSummary(final Set<ServerId>
managers) {
+
+ final Column COMPACTION_QUEUE_COL =
+ new Column(ServersView.RG_COL_KEY, "Compaction Queue", "Compaction
Queue", "");
+
+ List<ColumnFactory> cols =
ServersView.columnsFor(ServersView.ServerTable.COORDINATOR_QUEUES);
+
+ // Remove the column mapping for the resource group and replace it so that
+ // the column header reads "Compaction Queue" instead of "Resource Group"
+ int rgIdx = -1;
+ for (int idx = 0; idx < cols.size(); idx++) {
+ if (cols.get(idx).getColumn().key().equals(ServersView.RG_COL_KEY)) {
+ rgIdx = idx;
+ break;
+ }
+ }
+
+ if (rgIdx == -1) {
+ LOG.warn("Did not find Resource Group column to replace column header");
+ } else {
+ cols.remove(rgIdx);
+ cols.set(rgIdx, new ColumnFactory() {
+
+ @Override
+ public Column getColumn() {
+ return COMPACTION_QUEUE_COL;
+ }
+
+ @Override
+ public Object getRowData(ServerId sid, MetricResponse mr,
+ Map<String,List<FMetric>> serverMetrics) {
+ return sid.getResourceGroup().canonical();
+ }
+ });
+ }
+
+ // Construct a Map of MetricResponses by Queue. This method will take
+ // the provided MetricResponse and construct new ones that contain
+ // only the metrics with the "queue.id" tag in addition to the common
+ // server information (address, resource group, etc.).
+ Map<ServerId,MetricResponse> qm = new HashMap<>();
+
+ for (ServerId manager : managers) {
+ MetricResponse response = allMetrics.getIfPresent(manager);
+ if (response.getMetrics() != null) {
+
+ FMetric fm = new FMetric();
+ FTag t = new FTag();
+ for (final ByteBuffer binary : response.getMetrics()) {
+ fm = FMetric.getRootAsFMetric(binary, fm);
+ for (int i = 0; i < fm.tagsLength(); i++) {
+ t = fm.tags(t, i);
+ if (t.key().equals(QUEUE_TAG_KEY)) {
+ String queueName = t.value();
+ // For these MetricResponse objects we are going to put the
queueId value
+ // in the place of the resource group, we'll update the column
information
+ // for the resource group below.
+ ServerId sid = new ServerId(manager.getType(),
ResourceGroupId.of(queueName),
+ manager.getHost(), manager.getPort());
+ qm.computeIfAbsent(sid, (k) -> new
MetricResponse(response.getServerType(),
+ response.getServer(), queueName, response.getTimestamp(),
new ArrayList<>()))
+ .addToMetrics(binary);
+ break;
+ }
}
}
}
}
+
+ if (!qm.isEmpty()) {
+ // Create a ServersView object from the MetricResponse for each queue
+ return new ServersView(qm.keySet(), 0, qm, timestamp.get(), cols);
+ }
+ return new ServersView(Set.of(), 0, Map.of(), timestamp.get(), cols);
}
public void processResponse(final ServerId server, final MetricResponse
response) {
@@ -527,7 +602,6 @@ public class SystemInformation {
break;
case MANAGER:
managers.add(server);
- createCompactionSummary(response);
break;
case SCAN_SERVER:
sservers.computeIfAbsent(response.getResourceGroup(), (rg) ->
ConcurrentHashMap.newKeySet())
@@ -606,6 +680,7 @@ public class SystemInformation {
+ " group " + balancerRG + ", but there are no TabletServers.");
}
}
+
for (String rg : getResourceGroups()) {
Set<ServerId> rgCompactors = getCompactorResourceGroupServers(rg);
List<FMetric> metrics = queueMetrics.get(rg);
@@ -652,6 +727,19 @@ public class SystemInformation {
timestamp.set(System.currentTimeMillis());
+ for (Entry<TableId,LongAdder> e : runningCompactionsPerTable.entrySet()) {
+ TableId tid = e.getKey();
+ try {
+ tableCompactions.add(new CompactionTableSummary(tid.canonical(),
+ ctx.getQualifiedTableName(tid), e.getValue().sum()));
+ } catch (TableNotFoundException e1) {
+ LOG.warn("Error converting table id {} to table name, caught
TableNotFoundException", tid);
+ }
+ }
+
+ runningCompactionsPerGroup
+ .forEach((k, v) -> groupCompactions.add(new CompactionGroupSummary(k,
v.sum())));
+
for (final ServerId.Type type : ServerId.Type.values()) {
long problemHostCount =
problemHosts.stream().filter(serverId -> serverId.getType() ==
type).count();
@@ -673,6 +761,10 @@ public class SystemInformation {
cacheServerProcessView(ServersView.ServerTable.MANAGER_FATE,
servers, problemHostCount);
cacheServerProcessView(ServersView.ServerTable.MANAGER_COMPACTIONS,
servers,
problemHostCount);
+ ServersView coordinatorQueues =
createCompactionQueueSummary(servers);
+ serverMetricsView.put(ServersView.ServerTable.COORDINATOR_QUEUES,
+ memoize(() -> coordinatorQueues));
+
break;
case SCAN_SERVER:
sservers.values().forEach(servers::addAll);
@@ -706,6 +798,14 @@ public class SystemInformation {
return this.gc.get();
}
+ public List<CompactionGroupSummary> getRunningCompactionsPerGroup() {
+ return this.groupCompactions;
+ }
+
+ public List<CompactionTableSummary> getRunningCompactionsPerTable() {
+ return this.tableCompactions;
+ }
+
public Set<ServerId> getCompactorResourceGroupServers(String resourceGroup) {
return this.compactors.get(resourceGroup);
}
@@ -783,7 +883,7 @@ public class SystemInformation {
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))));
+ allMetrics.asMap(), timestamp.get(), ServersView.columnsFor(table))));
}
public ServersView getServerProcessView(ServersView.ServerTable table) {
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 49a8c313d0..4807155ff5 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
@@ -18,6 +18,10 @@
*/
package org.apache.accumulo.monitor.next.views;
+import static
org.apache.accumulo.monitor.next.views.ServersView.MetricFilterPrefixes.GC_WAL;
+import static
org.apache.accumulo.monitor.next.views.ServersView.MetricFilterPrefixes.MINC;
+import static
org.apache.accumulo.monitor.next.views.ServersView.MetricFilterPrefixes.MINC_COMPACTION;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -42,8 +46,6 @@ import
org.apache.accumulo.server.metrics.MetricResponseWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.github.benmanes.caffeine.cache.Cache;
-
/**
* Generic Data Transfer Object (DTO) for a set of Accumulo server processes
of the same type. The
* response object contains several fields:
@@ -86,6 +88,7 @@ public class ServersView {
* directly as the frontend table parameter values.
*/
public enum ServerTable {
+ COORDINATOR_QUEUES,
COMPACTORS,
GC_SUMMARY,
GC_FILES,
@@ -104,16 +107,21 @@ public class ServersView {
public static final String ADDR_COL_KEY = "serverAddress";
public static final String TIME_COL_KEY = "lastContact";
+ public static final Column LAST_CONTACT_COLUMN = new Column(TIME_COL_KEY,
"Last Contact",
+ "Time since the server last responded to the monitor", "duration");
+ public static final Column RG_COLUMN =
+ new Column(RG_COL_KEY, "Resource Group", "Resource Group", "");
+ public static final Column ADDR_COLUMN =
+ new Column(ADDR_COL_KEY, "Server Address", "Server address", "");
+
/**
* Common columns that are included in every ServersView table
*/
private static final List<ColumnFactory> COMMON_COLUMNS = List.of(new
ColumnFactory() {
- private final Column column = new Column(TIME_COL_KEY, "Last Contact",
- "Time since the server last responded to the monitor", "duration");
@Override
public Column getColumn() {
- return column;
+ return LAST_CONTACT_COLUMN;
}
@Override
@@ -122,11 +130,10 @@ public class ServersView {
return mr == null ? null : System.currentTimeMillis() -
mr.getTimestamp();
}
}, new ColumnFactory() {
- private final Column column = new Column(RG_COL_KEY, "Resource Group",
"Resource Group", "");
@Override
public Column getColumn() {
- return column;
+ return RG_COLUMN;
}
@Override
@@ -135,11 +142,10 @@ public class ServersView {
return sid.getResourceGroup().canonical();
}
}, new ColumnFactory() {
- private final Column column = new Column(ADDR_COL_KEY, "Server Address",
"Server address", "");
@Override
public Column getColumn() {
- return column;
+ return ADDR_COLUMN;
}
@Override
@@ -155,13 +161,13 @@ public class ServersView {
public final long timestamp;
public ServersView(final Set<ServerId> servers, final long
problemServerCount,
- final Cache<ServerId,MetricResponse> allMetrics, final long timestamp,
+ final Map<ServerId,MetricResponse> allMetrics, final long timestamp,
final List<ColumnFactory> requestedColumns) {
AtomicInteger serversMissingMetrics = new AtomicInteger(0);
// Grab the current metrics for each server
List<ServerMetricRow> serverMetricRows =
servers.stream().sorted().map(serverId -> {
- MetricResponse metricResponse = allMetrics.getIfPresent(serverId);
+ MetricResponse metricResponse = allMetrics.get(serverId);
boolean hasMetricData = hasMetricData(metricResponse);
Map<String,List<FMetric>> serverMetrics =
hasMetricData ? metricValuesByName(metricResponse) : Map.of();
@@ -407,6 +413,8 @@ public class ServersView {
List<ColumnFactory> cols = new ArrayList<>(COMMON_COLUMNS);
switch (table) {
+ case COORDINATOR_QUEUES ->
+ coordinatorQueueMetrics().forEach(m -> cols.add(new
MetricColumnFactory(m)));
case COMPACTORS -> compactorMetrics().forEach(m -> cols.add(new
MetricColumnFactory(m)));
case GC_SUMMARY -> gcSummaryMetrics().forEach(m -> cols.add(new
MetricColumnFactory(m)));
case GC_FILES -> gcFileMetrics().forEach(m -> cols.add(new
MetricColumnFactory(m)));
@@ -479,63 +487,86 @@ public class ServersView {
// TODO create scan problems that is a sum of zombie and low memory
}
+ // Filters to use with the metricList method
+ public static enum MetricFilterPrefixes {
+
+ GC_WAL("accumulo.gc.wal."), MINC("accumulo.minc"),
MINC_COMPACTION("accumulo.compaction.minc");
+
+ String prefix;
+
+ MetricFilterPrefixes(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+ }
+
/**
* The following helper methods are where the metrics included in each table
are defined as well
* as their order.
*/
+ private static List<Metric> coordinatorQueueMetrics() {
+ return metricList(m -> !m.getName().startsWith(MINC.getPrefix())
+ && !m.getName().startsWith(MINC_COMPACTION.getPrefix()),
MetricDocSection.COMPACTION);
+ }
+
private static List<Metric> compactorMetrics() {
- return metricList(MetricDocSection.GENERAL_SERVER,
MetricDocSection.COMPACTION,
+ return metricList(null, MetricDocSection.GENERAL_SERVER,
MetricDocSection.COMPACTION,
MetricDocSection.COMPACTOR);
}
private static List<Metric> gcSummaryMetrics() {
- return metricList(MetricDocSection.GENERAL_SERVER);
+ return metricList(null, 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();
+ return metricList((m) -> !m.getName().startsWith(GC_WAL.getPrefix()),
+ MetricDocSection.GARBAGE_COLLECTION);
}
private static List<Metric> gcWalMetrics() {
- return Arrays.stream(Metric.values())
- .filter(metric -> metric.getName().startsWith("accumulo.gc.wal."))
+ return Arrays.stream(Metric.values()).filter(m ->
m.getName().startsWith(GC_WAL.getPrefix()))
.collect(Collectors.toList());
}
private static List<Metric> managerMetrics() {
- return metricList(MetricDocSection.GENERAL_SERVER,
MetricDocSection.MANAGER);
+ return metricList(null, MetricDocSection.GENERAL_SERVER,
MetricDocSection.MANAGER);
}
private static List<Metric> managerFateMetrics() {
- return metricList(MetricDocSection.FATE);
+ return metricList(null, MetricDocSection.FATE);
}
private static List<Metric> managerCompactionMetrics() {
- return metricList(MetricDocSection.COMPACTION);
+ return metricList(m -> !m.getName().startsWith(MINC.getPrefix())
+ && !m.getName().startsWith(MINC_COMPACTION.getPrefix()),
MetricDocSection.COMPACTION);
}
private static List<Metric> scanServerMetrics() {
- return metricList(MetricDocSection.GENERAL_SERVER,
MetricDocSection.SCAN_SERVER,
+ return metricList(null, MetricDocSection.GENERAL_SERVER,
MetricDocSection.SCAN_SERVER,
MetricDocSection.SCAN, MetricDocSection.BLOCK_CACHE);
}
private static List<Metric> tabletServerMetrics() {
- return metricList(MetricDocSection.GENERAL_SERVER,
MetricDocSection.TABLET_SERVER,
+ return metricList(null, 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());
+ private static List<Metric> metricList(Predicate<Metric> filter,
MetricDocSection... sections) {
+ Predicate<Metric> sectionPredicate = null;
+ if (sections == null) {
+ sectionPredicate = m -> false;
+ } else {
+ Set<MetricDocSection> requestedSections = Set.of(sections);
+ sectionPredicate = m -> requestedSections.contains(m.getDocSection());
+ }
+ return Arrays.stream(Metric.values()).filter(sectionPredicate)
+ .filter(filter == null ? m -> true :
filter).collect(Collectors.toList());
}
public static Number add(Number n1, Number n2) {
diff --git
a/server/monitor/src/main/java/org/apache/accumulo/monitor/view/WebViews.java
b/server/monitor/src/main/java/org/apache/accumulo/monitor/view/WebViews.java
index b142128b79..1f67affd68 100644
---
a/server/monitor/src/main/java/org/apache/accumulo/monitor/view/WebViews.java
+++
b/server/monitor/src/main/java/org/apache/accumulo/monitor/view/WebViews.java
@@ -258,6 +258,23 @@ public class WebViews {
return model;
}
+ /**
+ * Returns the compactors template
+ *
+ * @return Compactors model
+ */
+ @GET
+ @Path("coordinator")
+ @Template(name = "/default.ftl")
+ public Map<String,Object> getCompactionOverview() {
+ Map<String,Object> model = getModel();
+ model.put("title", "Compaction Overview");
+ model.put("template", "coordinator.ftl");
+ model.put("js", "coordinator.js");
+
+ return model;
+ }
+
/**
* Returns the compactors template
*
diff --git
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/coordinator.js
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/coordinator.js
new file mode 100644
index 0000000000..849288b7ce
--- /dev/null
+++
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/coordinator.js
@@ -0,0 +1,134 @@
+/*
+ * 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 coordinatorHtmlTable = '#coordinators';
+const queuesHtmlTable = '#coordinator_queues';
+const runningTableHtmlTable = '#table_running';
+const runningQueueHtmlTable = '#queue_running';
+
+var tableRunning;
+var queueRunning;
+
+function getStoredArray(storageKey) {
+ if (!sessionStorage[storageKey]) {
+ return [];
+ }
+ return JSON.parse(sessionStorage[storageKey]);
+}
+
+function refresh() {
+ $.when(getRunningCompactionsByTable(), getRunningCompactionsByGroup(),
getCoordinatorQueueView(), getManagersCompactionView()).then(function () {
+ refreshTable(coordinatorHtmlTable, MANAGER_COMPACTION_SERVER_PROCESS_VIEW);
+ refreshTable(queuesHtmlTable, COORDINATOR_QUEUE_PROCESS_VIEW);
+ ajaxReloadTable(tableRunning);
+ ajaxReloadTable(queueRunning);
+ }).fail(function () {
+ sessionStorage[MANAGER_COMPACTION_SERVER_PROCESS_VIEW] = JSON.stringify({
+ data: [],
+ columns: [],
+ status: null
+ });
+ sessionStorage[COORDINATOR_QUEUE_PROCESS_VIEW] = JSON.stringify({
+ data: [],
+ columns: [],
+ status: null
+ });
+ sessionStorage[RUNNING_COMPACTIONS_BY_TABLE] = JSON.stringify([]);
+ sessionStorage[RUNNING_COMPACTIONS_BY_GROUP] = JSON.stringify([]);
+ refreshTable(coordinatorHtmlTable, MANAGER_COMPACTION_SERVER_PROCESS_VIEW);
+ refreshTable(queuesHtmlTable, COORDINATOR_QUEUE_PROCESS_VIEW);
+ ajaxReloadTable(tableRunning);
+ ajaxReloadTable(queueRunning);
+ $(coordinatorHtmlTable).hide();
+ $(queuesHtmlTable).hide();
+ $(runningTableHtmlTable).hide();
+ $(runningQueueHtmlTable).hide();
+ });
+}
+
+$(function () {
+ sessionStorage[MANAGER_COMPACTION_SERVER_PROCESS_VIEW] = JSON.stringify({
+ data: [],
+ columns: [],
+ status: null
+ });
+ sessionStorage[COORDINATOR_QUEUE_PROCESS_VIEW] = JSON.stringify({
+ data: [],
+ columns: [],
+ status: null
+ });
+ sessionStorage[RUNNING_COMPACTIONS_BY_TABLE] = JSON.stringify([]);
+ sessionStorage[RUNNING_COMPACTIONS_BY_GROUP] = JSON.stringify([]);
+
+ // Create a table for scans list
+ tableRunning = $(runningTableHtmlTable).DataTable({
+ "ajax": function (data, callback) {
+ callback({
+ data: getStoredArray(RUNNING_COMPACTIONS_BY_TABLE)
+ });
+ },
+ "stateSave": true,
+ "colReorder": true,
+ "columnDefs": [{
+ targets: '_all',
+ defaultContent: '-'
+ },
+ {
+ "targets": 0,
+ "render": function (data, type, row) {
+ if (type === 'display') {
+ data = '<a href="tables/' + row.tableId + '">' + row.tableName +
'</a>';
+ }
+ return data;
+ }
+ }
+ ],
+ "columns": [{
+ "data": "tableName"
+ },
+ {
+ "data": "running"
+ }
+ ]
+ });
+
+ queueRunning = $(runningQueueHtmlTable).DataTable({
+ "ajax": function (data, callback) {
+ callback({
+ data: getStoredArray(RUNNING_COMPACTIONS_BY_GROUP)
+ });
+ },
+ "stateSave": true,
+ "colReorder": true,
+ "columnDefs": [{
+ targets: '_all',
+ defaultContent: '-'
+ }],
+ "columns": [{
+ "data": "groupId"
+ },
+ {
+ "data": "running"
+ }
+ ]
+ });
+
+ refresh();
+});
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 50fb150ed5..2d4a2c3260 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
@@ -26,6 +26,7 @@ const REST_V2_PREFIX = contextPath + 'rest-v2';
const MANAGER_GOAL_STATE_METRIC = 'accumulo.manager.goal.state';
const COMPACTOR_SERVER_PROCESS_VIEW = 'compactorsView';
+const COORDINATOR_QUEUE_PROCESS_VIEW = 'coordinatorQueueView';
const GC_SERVER_PROCESS_VIEW = 'gcSummaryView';
const GC_FILE_SERVER_PROCESS_VIEW = 'gcFileView';
const GC_WAL_SERVER_PROCESS_VIEW = 'gcWalView';
@@ -34,6 +35,8 @@ 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';
+const RUNNING_COMPACTIONS_BY_TABLE = 'runningCompactionsByTable';
+const RUNNING_COMPACTIONS_BY_GROUP = 'runningCompactionsByGroup';
// Override Length Menu options for dataTables
if ($.fn && $.fn.dataTable) {
@@ -686,6 +689,10 @@ function getCompactorsView() {
return getServerProcessView('COMPACTORS', COMPACTOR_SERVER_PROCESS_VIEW);
}
+function getCoordinatorQueueView() {
+ return getServerProcessView('COORDINATOR_QUEUES',
COORDINATOR_QUEUE_PROCESS_VIEW);
+}
+
function getGcView() {
return getServerProcessView('GC_SUMMARY', GC_SERVER_PROCESS_VIEW);
}
@@ -773,6 +780,23 @@ function getCompactionsSummary() {
return getJSONForTable(REST_V2_PREFIX + '/compactions/summary',
'compactionsSummary');
}
+/**
+ * REST GET call for /compactions/running/table,
+ * stores it on a sessionStorage variable
+ */
+function getRunningCompactionsByTable() {
+ return getJSONForTable(REST_V2_PREFIX + '/compactions/running/table',
RUNNING_COMPACTIONS_BY_TABLE);
+}
+
+/**
+ * REST GET call for /compactions/running/group,
+ * stores it on a sessionStorage variable
+ */
+function getRunningCompactionsByGroup() {
+ return getJSONForTable(REST_V2_PREFIX + '/compactions/running/group',
RUNNING_COMPACTIONS_BY_GROUP);
+}
+
+
/**
* Returns true if the input is a valid regular expression, false otherwise.
*
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 58ddbb2f88..0e20a8716d 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
@@ -25,7 +25,6 @@ const managerStateBanner = '#managerStateBanner'
const managerStateBannerMessage = '#manager-state-message'
const htmlTable = '#managers'
const fateHtmlTable = '#managers_fate'
-const compactionHtmlTable = '#managers_compactions'
function updateManagerGoalStateBanner() {
const goalState = getManagerGoalStateFromSession();
@@ -47,22 +46,19 @@ function refreshManagerBanners() {
$(runningBanner).show();
$(htmlTable).hide();
$(fateHtmlTable).hide();
- $(compactionHtmlTable).hide();
} else {
// otherwise, hide the error banner and show manager table
$(runningBanner).hide();
$(fateHtmlTable).show();
$(htmlTable).show();
- $(compactionHtmlTable).show();
}
updateManagerGoalStateBanner();
}
function refresh() {
- $.when(getManagersView(), getManagersFateView(),
getManagersCompactionView()).then(function () {
+ $.when(getManagersView(), getManagersFateView()).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 () {
@@ -76,18 +72,11 @@ function refresh() {
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);
});
@@ -104,11 +93,6 @@ $(function () {
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/templates/coordinator.ftl
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/coordinator.ftl
new file mode 100644
index 0000000000..259fc282b8
--- /dev/null
+++
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/coordinator.ftl
@@ -0,0 +1,54 @@
+<#--
+
+ 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.
+
+-->
+ <br />
+ <table id="coordinators" class="table caption-top table-bordered
table-striped table-condensed">
+ <caption><span class="table-caption">Compaction Coordinator
Activity</span><br /></caption>
+ <tbody></tbody>
+ </table>
+ <br />
+ <table id="coordinator_queues" class="table caption-top table-bordered
table-striped table-condensed">
+ <caption><span class="table-caption">Compaction Coordinator
Queues</span><br /></caption>
+ <tbody></tbody>
+ </table>
+ <br />
+ <table id="table_running" class="table caption-top table-bordered
table-striped table-condensed">
+ <caption><span class="table-caption">Running Compactions By
Table</span><br /></caption>
+ <thead>
+ <tr>
+ <th>Table Name</th>
+ <th>Running Compactions</th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ <br />
+ <table id="queue_running" class="table caption-top table-bordered
table-striped table-condensed">
+ <caption><span class="table-caption">Running Compactions By
Queue</span><br /></caption>
+ <thead>
+ <tr>
+ <th>Queue Name</th>
+ <th>Running Compactions</th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ <br />
+
\ No newline at end of file
diff --git
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/manager.ftl
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/manager.ftl
index d60f17e157..6c1040529c 100644
---
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/manager.ftl
+++
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/manager.ftl
@@ -32,11 +32,6 @@
<tbody></tbody>
</table>
<br />
- <table id="managers_compactions" class="table caption-top table-bordered
table-striped table-condensed">
- <caption><span class="table-caption">Manager Compaction
Activity</span><br /></caption>
- <tbody></tbody>
- </table>
- <br />
<table id="managers_fate" class="table caption-top table-bordered
table-striped table-condensed">
<caption><span class="table-caption">Manager Fate Activity</span><br
/></caption>
<tbody></tbody>
diff --git
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/navbar.ftl
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/navbar.ftl
index 3be1576833..1cf41fcd89 100644
---
a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/navbar.ftl
+++
b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/navbar.ftl
@@ -54,9 +54,10 @@
Activity
</a>
<ul class="dropdown-menu col-xs-12"
aria-labelledby="navbarDropdown">
- <li><a class="dropdown-item"
href="ec">Active Compactions</a></li>
- <li><a class="dropdown-item"
href="scans">Active Scans</a></li>
<li><a class="dropdown-item"
href="bulkImports">Bulk Imports</a></li>
+ <li><a class="dropdown-item" href="coordinator">Compaction
Overview</a></li>
+ <li><a class="dropdown-item" href="ec">Compaction
Details</a></li>
+ <li><a class="dropdown-item" href="scans">Scans</a></li>
</ul>
</li>
<li class="dropdown">