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 72dfc4a1360..f5719637b2e 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 @@ -31,6 +31,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; import jakarta.inject.Inject; @@ -448,6 +449,14 @@ public Set getMessageCategories() { public record Message(String priority, String category, String message) { } + @GET + @Path("message/counts") + @Produces(MediaType.APPLICATION_JSON) + @Description("Returns count of messages by priority") + public Map getMessageCounts() { + return monitor.getInformationFetcher().getSummaryForEndpoint().getMessageCounts(); + } + @GET @Path("messages") @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 e5d7491f58c..a00a1906ec6 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 @@ -521,6 +521,8 @@ public List getTabletsNeedingRecovery() { private final Map>> messages = new EnumMap<>(MessagePriority.class); + private final EnumMap messageCounts = + new EnumMap<>(MessagePriority.class); private final Set configuredCompactionResourceGroups = ConcurrentHashMap.newKeySet(); @@ -538,6 +540,9 @@ public SystemInformation(Cache allMetrics, ServerContex this.ctx = ctx; this.rgLongRunningCompactionSize = this.ctx.getConfiguration().getCount(Property.MONITOR_LONG_RUNNING_COMPACTION_LIMIT); + for (MessagePriority p : MessagePriority.values()) { + messageCounts.put(p, new AtomicLong(0)); + } } public void clear() { @@ -570,16 +575,25 @@ public void clear() { componentStatuses.clear(); managerGoalState = null; serverMetricsView.clear(); + messageCounts.clear(); } public void addMessage(MessagePriority pri, MessageCategory cat, String msg) { messages.computeIfAbsent(pri, k -> new EnumMap<>(MessageCategory.class)) .computeIfAbsent(cat, k -> new TreeSet<>()).add(msg); + messageCounts.get(pri).incrementAndGet(); } public void removeMessage(MessagePriority pri, MessageCategory cat, String part) { messages.getOrDefault(pri, new EnumMap<>(MessageCategory.class)) .getOrDefault(cat, new HashSet()).removeIf(s -> s.contains(part)); + messageCounts.get(pri).updateAndGet(val -> { + if (val > 0) { + return val - 1; + } else { + return 0; + } + }); } private void updateAggregates(final MetricResponse response, @@ -1352,6 +1366,10 @@ public Map>> getMessages() { return this.messages; } + public Map getMessageCounts() { + return this.messageCounts; + } + public long getTimestamp() { return this.timestamp.get(); } 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 093d2d1d75e..15adaf03975 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 @@ -40,6 +40,7 @@ const RUNNING_COMPACTIONS_BY_GROUP = 'runningCompactionsByGroup'; const AUTO_REFRESH_KEY = 'auto-refresh'; const MESSAGE_CATEGORIES = 'messageCategories'; const MESSAGES = 'messages'; +const MESSAGE_COUNTS = 'messageCounts' const RECOVERY = 'recovery'; // Override Length Menu options for dataTables @@ -547,6 +548,14 @@ function getMessageCategories() { return getJSONForTable(REST_V2_PREFIX + '/message/categories', MESSAGE_CATEGORIES); } +/** + * REST GET call for /message/counts + * store it on a sessionStorage variable + */ +function getMessageCounts() { + return getJSONForTable(REST_V2_PREFIX + '/message/counts', MESSAGE_COUNTS); +} + /** * REST GET call for /messages, * results are not stored in session as this diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/navbar.js b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/navbar.js index 7b6dfce77ff..0c189775987 100644 --- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/navbar.js +++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/js/navbar.js @@ -149,6 +149,7 @@ $(function () { setTheme(); updateDarkThemeSwitch(); refreshSidebar(); + refreshMessageBadge(); }); /** @@ -165,6 +166,7 @@ function refreshSidebar() { */ function refreshNavBar() { refreshSidebar(); + refreshMessageBadge(); } /** @@ -220,3 +222,32 @@ function updateDarkThemeSwitch() { document.documentElement.setAttribute('data-bs-theme', enableDarkTheme ? 'dark' : 'light'); }); } + +/** + * Updates the badge on the Messages label on the Nav Bar + */ +function refreshMessageBadge() { + getMessageCounts().then(function () { + + var messageAnchor = $('#message-anchor'); + + var msgCounts = getStoredJson(MESSAGE_COUNTS, { + "Critical": 0, + "High": 0, + "Info": 0 + }); + var critMsgCount = msgCounts.Critical; + var highMsgCount = msgCounts.High; + + messageAnchor.find('span').remove(); + + if (critMsgCount > 0) { + messageAnchor.append('' + + critMsgCount + ''); + } else if (highMsgCount > 0) { + messageAnchor.append( + '' + + highMsgCount + ''); + } + }); +} 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 fc188ca6187..7b1eb8e501f 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 @@ -62,7 +62,7 @@
  • - Messages + Messages