This is an automated email from the ASF dual-hosted git repository.

vjasani pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 257c928cff AMBARI-26316: Add metrics for Agent Stomp and Api Stomp 
performance (#3949)
257c928cff is described below

commit 257c928cff1bf14fdb195ebb155f69d904313526
Author: Sandeep  Kumar <[email protected]>
AuthorDate: Fri Jun 13 04:49:47 2025 +0530

    AMBARI-26316: Add metrics for Agent Stomp and Api Stomp performance (#3949)
---
 .../src/test/resources/metrics.properties          |    1 +
 ambari-server/conf/unix/metrics.properties         |    3 +-
 .../ambari/server/controller/AmbariServer.java     |    9 +
 .../metrics/system/impl/MetricsConfiguration.java  |   26 +
 .../metrics/system/impl/MetricsServiceImpl.java    |   17 +
 .../system/impl/StompStatsMetricsSource.java       |  128 ++
 .../default/grafana-ambari-server-stats.json       | 1619 ++++++++++++++++++++
 .../system/impl/StompStatsMetricsSourceTest.java   |  112 ++
 8 files changed, 1914 insertions(+), 1 deletion(-)

diff --git a/ambari-funtest/src/test/resources/metrics.properties 
b/ambari-funtest/src/test/resources/metrics.properties
index 6433295913..9236120ecc 100644
--- a/ambari-funtest/src/test/resources/metrics.properties
+++ b/ambari-funtest/src/test/resources/metrics.properties
@@ -21,3 +21,4 @@
 # Source interval determines how often the metric is sent to sink. Its unit is 
in seconds
 metric.sources=jvm
 source.jvm.class=org.apache.ambari.server.metrics.system.impl.JvmMetricsSource
+source.stats.class=org.apache.ambari.server.metrics.system.impl.StompStatsMetricsSource
diff --git a/ambari-server/conf/unix/metrics.properties 
b/ambari-server/conf/unix/metrics.properties
index 96748d29b0..2d76731f14 100644
--- a/ambari-server/conf/unix/metrics.properties
+++ b/ambari-server/conf/unix/metrics.properties
@@ -19,12 +19,13 @@
 
 #################### Metrics Source Configs #####################
 
-#Metric sources : jvm,database
+#Metric sources : jvm,database, stats
 metric.sources=jvm,event
 
 #### JVM Source Configs ###
 source.jvm.class=org.apache.ambari.server.metrics.system.impl.JvmMetricsSource
 
source.event.class=org.apache.ambari.server.metrics.system.impl.StompEventsMetricsSource
+source.stats.class=org.apache.ambari.server.metrics.system.impl.StompStatsMetricsSource
 source.jvm.interval=10
 
 #### Database Source Configs ###
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 1e5d7d3d4b..a56be88346 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -86,6 +86,8 @@ import 
org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.ldap.LdapModule;
 import org.apache.ambari.server.listeners.WebSocketInitializerListener;
 import org.apache.ambari.server.metrics.system.MetricsService;
+import org.apache.ambari.server.metrics.system.impl.MetricsConfiguration;
+import org.apache.ambari.server.metrics.system.impl.MetricsServiceImpl;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.PersistenceType;
 import org.apache.ambari.server.orm.dao.BlueprintDAO;
@@ -166,6 +168,7 @@ import 
org.springframework.web.context.request.RequestContextListener;
 import 
org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
 import org.springframework.web.filter.DelegatingFilterProxy;
 import org.springframework.web.servlet.DispatcherServlet;
+import org.springframework.web.socket.config.WebSocketMessageBrokerStats;
 
 import com.google.common.base.Joiner;
 import com.google.common.util.concurrent.ServiceManager;
@@ -598,6 +601,12 @@ public class AmbariServer {
       LOG.info("********* Started Services **********");
 
       if (!configs.isMetricsServiceDisabled()) {
+        if (MetricsConfiguration.isStompStatMetricsConfigured() && 
metricsService instanceof MetricsServiceImpl) {
+          WebSocketMessageBrokerStats apiStompStats = 
apiDispatcherContext.getBean(WebSocketMessageBrokerStats.class);
+          ((MetricsServiceImpl) 
metricsService).setApiStompStats(apiStompStats);
+          WebSocketMessageBrokerStats agentStompStats = 
agentDispatcherContext.getBean(WebSocketMessageBrokerStats.class);
+          ((MetricsServiceImpl) 
metricsService).setAgentStompStats(agentStompStats);
+        }
         metricsService.start();
       } else {
         LOG.info("AmbariServer Metrics disabled.");
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsConfiguration.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsConfiguration.java
index 28556f608d..4d87fb11c5 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsConfiguration.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsConfiguration.java
@@ -124,4 +124,30 @@ public class MetricsConfiguration {
 
     return new MetricsConfiguration(subsetProperties);
   }
+
+  /**
+   * For enabling stompStats Metrics, append 'stats' in metric.sources.
+   * @return true if StompStatsMetricsSource is configured, false otherwise.
+   */
+  public static boolean isStompStatMetricsConfigured() {
+    MetricsConfiguration configuration = getMetricsConfiguration();
+    String commaSeparatedSources = configuration.getProperty("metric.sources");
+    if (StringUtils.isEmpty(commaSeparatedSources)) {
+      return false;
+    }
+
+    String[] sourceNames = commaSeparatedSources.split(",");
+    for (String sourceName : sourceNames) {
+      if (StringUtils.isEmpty(sourceName)) {
+        continue;
+      }
+      sourceName = sourceName.trim();
+
+      String className = configuration.getProperty("source." + sourceName + 
".class");
+      if (className.equals(StompStatsMetricsSource.class.getName())) {
+        return true;
+      }
+    }
+    return false;
+  }
 }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsServiceImpl.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsServiceImpl.java
index 03f67ada65..a1c78a3a45 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsServiceImpl.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsServiceImpl.java
@@ -30,6 +30,7 @@ import org.apache.ambari.server.metrics.system.MetricsSource;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.web.socket.config.WebSocketMessageBrokerStats;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -46,6 +47,9 @@ public class MetricsServiceImpl implements MetricsService {
   @Inject
   STOMPUpdatePublisher STOMPUpdatePublisher;
 
+  private WebSocketMessageBrokerStats apiStompStats;
+  private WebSocketMessageBrokerStats agentStompStats;
+
   @Override
   public void start() {
     LOG.info("********* Initializing AmbariServer Metrics Service **********");
@@ -119,6 +123,11 @@ public class MetricsServiceImpl implements MetricsService {
           STOMPUpdatePublisher.registerAPI(src);
           STOMPUpdatePublisher.registerAgent(src);
         }
+
+        if (src instanceof StompStatsMetricsSource && apiStompStats != null && 
agentStompStats != null) {
+          ((StompStatsMetricsSource) src).setApiStompStats(apiStompStats);
+          ((StompStatsMetricsSource) src).setAgentStompStats(agentStompStats);
+        }
         src.start();
       }
 
@@ -134,4 +143,12 @@ public class MetricsServiceImpl implements MetricsService {
   public static MetricsSink getSink() {
     return sink;
   }
+
+  public void setApiStompStats(WebSocketMessageBrokerStats apiStompStats) {
+    this.apiStompStats = apiStompStats;
+  }
+
+  public void setAgentStompStats(WebSocketMessageBrokerStats agentStompStats) {
+    this.agentStompStats = agentStompStats;
+  }
 }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/StompStatsMetricsSource.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/StompStatsMetricsSource.java
new file mode 100644
index 0000000000..c2f3c54c4a
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/StompStatsMetricsSource.java
@@ -0,0 +1,128 @@
+/*
+ * 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
+ *
+ *     http://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.ambari.server.metrics.system.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.apache.ambari.server.metrics.system.SingleMetric;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.socket.config.WebSocketMessageBrokerStats;
+
+/**
+ * Gets the metrics about stomp stats connections and publishes to configured
+ * Metric Sink.
+ */
+public class StompStatsMetricsSource extends AbstractMetricsSource {
+    public static final String[] metricsTypes = { "stomp.api", "stomp.agent" };
+    public static final String[] poolMetrics = { "pool_size", 
"active_threads", "queued_tasks", "completed_tasks" };
+    public static final String[] webSocketMetrics = { 
"current_client_session", "current_web_socket_session",
+            "current_http_stream", "current_http_polling",
+            "total_sessions_established", "abnormally_closed_session", 
"connect_failure_session",
+            "send_time_limit_exceeded", "transport_errors_sessions" };
+    public static final String[] stompSubProtocolMetrics = { "connect", 
"connected", "disconnect" };
+    private WebSocketMessageBrokerStats apiStompStats;
+    private WebSocketMessageBrokerStats agentStompStats;
+    private static final Logger LOG = 
LoggerFactory.getLogger(StompEventsMetricsSource.class);
+    private final ScheduledExecutorService executor = 
Executors.newScheduledThreadPool(1);
+
+    @Override
+    public void start() {
+        int interval = 60;
+        LOG.info("Starting stomp stat source.");
+        try {
+            executor.scheduleWithFixedDelay(new Runnable() {
+                @Override
+                public void run() {
+                    List<SingleMetric> events = getStompStatMetrics();
+                    if (!events.isEmpty()) {
+                        sink.publish(events);
+                        LOG.debug("********* Published stomp stat metrics to 
sink **********");
+                    }
+                }
+            }, interval, interval, TimeUnit.SECONDS);
+        } catch (Exception e) {
+            LOG.info("Failed to start stomp stat source", e);
+        }
+    }
+
+    protected List<SingleMetric> getStompStatMetrics() {
+        List<SingleMetric> metrics = new ArrayList<>();
+        populateStompStatMetrics(metrics, metricsTypes[0], apiStompStats);
+        populateStompStatMetrics(metrics, metricsTypes[1], agentStompStats);
+        return metrics;
+    }
+
+    private void populateStompStatMetrics(List<SingleMetric> metricsList, 
String metricsPrefix,
+            WebSocketMessageBrokerStats stompStats) {
+        parseStats(metricsList, metricsPrefix + ".websocket.", 
webSocketMetrics,
+                stompStats.getWebSocketSessionStatsInfo());
+        parseStats(metricsList, metricsPrefix + ".stomp_sub_protocol.", 
stompSubProtocolMetrics,
+                stompStats.getStompSubProtocolStatsInfo());
+        parseStats(metricsList, metricsPrefix + ".inbound_channel.", 
poolMetrics,
+                stompStats.getClientInboundExecutorStatsInfo());
+        parseStats(metricsList, metricsPrefix + ".outbound_channel.", 
poolMetrics,
+                stompStats.getClientOutboundExecutorStatsInfo());
+        parseStats(metricsList, metricsPrefix + ".sockJsScheduler.", 
poolMetrics,
+                stompStats.getSockJsTaskSchedulerStatsInfo());
+    }
+
+    private void parseStats(List<SingleMetric> metricsList, String 
metricsPrefix, String[] metricsNamesList,
+            String stats) {
+        if (stats.equals("null")) {
+            LOG.warn("stats for " + metricsPrefix + " is null");
+            return;
+        }
+        List<Long> statsArray = getValuesFromString(stats);
+
+        // sanity check to make sure we have the same number of metrics and 
values.
+        if (statsArray.size() != metricsNamesList.length) {
+            LOG.error("Number of metrics and stats do not match for " + 
metricsPrefix);
+            return;
+        }
+        long currentTimeMillis = System.currentTimeMillis();
+        for (int i = 0; i < metricsNamesList.length; i++) {
+            metricsList
+                    .add(new SingleMetric(metricsPrefix + metricsNamesList[i], 
statsArray.get(i), currentTimeMillis));
+        }
+    }
+
+    private List<Long> getValuesFromString(String stats) {
+        // '\\D+' matches one or more non-digit characters. After that it 
split the
+        // string and filter out empty strings. Then we convert the string to 
long.
+        return Arrays.stream(stats.split("\\D+"))
+                .filter(s -> !s.isEmpty())
+                .map(Long::parseLong)
+                .collect(Collectors.toList());
+    }
+
+    public void setApiStompStats(WebSocketMessageBrokerStats apiStompStats) {
+        this.apiStompStats = apiStompStats;
+    }
+
+    public void setAgentStompStats(WebSocketMessageBrokerStats 
agentStompStats) {
+        this.agentStompStats = agentStompStats;
+    }
+}
diff --git 
a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/3.0.0/package/files/grafana-dashboards/default/grafana-ambari-server-stats.json
 
b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/3.0.0/package/files/grafana-dashboards/default/grafana-ambari-server-stats.json
new file mode 100644
index 0000000000..0a5d7504bf
--- /dev/null
+++ 
b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/3.0.0/package/files/grafana-dashboards/default/grafana-ambari-server-stats.json
@@ -0,0 +1,1619 @@
+{
+    "id": null,
+    "title": "Ambari Server Stomp Stats",
+    "originalTitle": "Ambari Server Stats",
+    "tags": [
+      "ambari_server"
+    ],
+    "style": "dark",
+    "timezone": "browser",
+    "editable": true,
+    "hideControls": false,
+    "sharedCrosshair": false,
+    "rows": [
+      {
+        "collapse": false,
+        "editable": true,
+        "height": "100px",
+        "panels": [
+          {
+            "content": "<h4 align=\"center\">Metrics to see the overall status 
for Stomp Stats. Click on each row title to expand on demand to look at various 
metrics. </h4>",
+            "editable": true,
+            "error": false,
+            "id": 22,
+            "isNew": true,
+            "links": [],
+            "mode": "html",
+            "span": 12,
+            "style": {},
+            "title": "",
+            "type": "text"
+          }
+        ],
+        "title": "Stomp Stats"
+      },
+      {
+        "collapse": true,
+        "editable": true,
+        "height": "250px",
+        "panels": [
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 11,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "current_client_session",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.current_client_session",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform":"none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "current_web_socket_session",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.current_web_socket_session",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "current_http_stream",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.current_http_stream",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "current_http_polling",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.current_http_polling",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "API Web Socket Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          },
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 12,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "current_client_session",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.current_client_session",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "current_web_socket_session",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.current_web_socket_session",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "current_http_stream",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.current_http_stream",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "current_http_polling",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.current_http_polling",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Agent Web Socket Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          },
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 13,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "total_sessions_established",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.total_sessions_established",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "abnormally_closed_session",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.abnormally_closed_session",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "connect_failure_session",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.connect_failure_session",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "send_time_limit_exceeded",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.send_time_limit_exceeded",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              },
+              {
+                "aggregator": "none",
+                "alias": "transport_errors_sessions",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.websocket.transport_errors_sessions",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "E"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "API Web Socket Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          },
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 14,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "total_sessions_established",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.total_sessions_established",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "abnormally_closed_session",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.abnormally_closed_session",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "connect_failure_session",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.connect_failure_session",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "send_time_limit_exceeded",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.send_time_limit_exceeded",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              },
+              {
+                "aggregator": "none",
+                "alias": "transport_errors_sessions",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.websocket.transport_errors_sessions",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "E"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Agent Web Socket Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          }
+        ],
+        "showTitle": true,
+        "title": "Web Socket Stats"
+      },
+      {
+        "collapse": true,
+        "editable": true,
+        "height": "250px",
+        "panels": [
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 15,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "connect",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.stomp_sub_protocol.connnect",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "connected",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.stomp_sub_protocol.connected",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "disconnect",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.stomp_sub_protocol.disconnect",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "API Stomp SubProtocol Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          },
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 16,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "connect",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.stomp_sub_protocol.connnect",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "connected",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.stomp_sub_protocol.connected",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "disconnect",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.stomp_sub_protocol.disconnect",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Agent Stomp SubProtocol Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          }
+        ],
+        "showTitle": true,
+        "title": "Stomp SubProtocol Stats"
+      },
+      {
+        "collapse": true,
+        "editable": true,
+        "height": "250px",
+        "panels": [
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 19,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "Pool size",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.inbound_channel.pool_size",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "active threads",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.inbound_channel.active_threads",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "queued tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.inbound_channel.queued_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "completed tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.inbound_channel.completed_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "API Client Inbound Executor Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          },
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 20,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "Pool size",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.inbound_channel.pool_size",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "active threads",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.inbound_channel.active_threads",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "queued tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.inbound_channel.queued_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "completed tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.inbound_channel.completed_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Agent Client Inbound Executor Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          }
+        ],
+        "showTitle": true,
+        "title": "Client Inbound Executor Stats"
+      },
+      {
+        "collapse": true,
+        "editable": true,
+        "height": "250px",
+        "panels": [
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 21,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "Pool size",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.outbound_channel.pool_size",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "active threads",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.outbound_channel.active_threads",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "queued tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.outbound_channel.queued_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "completed tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.outbound_channel.completed_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "API Client Outbound executor Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          },
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 22,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "Pool size",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.outbound_channel.pool_size",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "active threads",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.outbound_channel.active_threads",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "queued tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.outbound_channel.queued_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "completed tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.outbound_channel.completed_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Agent Client Outbound executor Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          }
+        ],
+        "showTitle": true,
+        "title": "Client Outbound executor Stats"
+      },
+      {
+        "collapse": true,
+        "editable": true,
+        "height": "250px",
+        "panels": [
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 23,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "Pool size",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.sockJsScheduler.pool_size",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "active threads",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.sockJsScheduler.active_threads",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "queued tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.sockJsScheduler.queued_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "completed tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.api.sockJsScheduler.completed_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "API sockJs Task Scheduler Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          },
+          {
+            "aliasColors": {},
+            "bars": false,
+            "datasource": null,
+            "editable": true,
+            "error": false,
+            "fill": 0,
+            "grid": {
+              "leftLogBase": 10,
+              "leftMax": null,
+              "leftMin": 0,
+              "rightLogBase": 1,
+              "rightMax": null,
+              "rightMin": 0,
+              "threshold1": null,
+              "threshold1Color": "rgba(216, 200, 27, 0.27)",
+              "threshold2": null,
+              "threshold2Color": "rgba(234, 112, 112, 0.22)"
+            },
+            "id": 24,
+            "isNew": true,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "connected",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "aggregator": "none",
+                "alias": "Pool size",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.sockJsScheduler.pool_size",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "A"
+              },
+              {
+                "aggregator": "none",
+                "alias": "active threads",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.sockJsScheduler.active_threads",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "B"
+              },
+              {
+                "aggregator": "none",
+                "alias": "queued tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.sockJsScheduler.queued_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "C"
+              },
+              {
+                "aggregator": "none",
+                "alias": "completed tasks",
+                "app": "ambari_server",
+                "downsampleAggregator": "avg",
+                "errors": {},
+                "metric": "stomp.agent.sockJsScheduler.completed_tasks",
+                "precision": "default",
+                "seriesAggregator": "none",
+                "transform": "none",
+                "refId": "D"
+              }
+            ],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Agent sockJs Task Scheduler Stats",
+            "tooltip": {
+              "shared": true,
+              "value_type": "cumulative"
+            },
+            "type": "graph",
+            "xaxis": {
+              "mode": "time",
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "$$hashKey": "object:86",
+                "format": "none",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              },
+              {
+                "$$hashKey": "object:87",
+                "logBase": 1,
+                "min": 0,
+                "show": true
+              }
+            ],
+            "yaxis": {
+              "align": false
+            }
+          }
+        ],
+        "showTitle": true,
+        "title": "Get Sock JS Task Scheduler Stats"
+      }
+    ],
+    "time": {
+      "from": "now-6h",
+      "to": "now"
+    },
+    "timepicker": {
+      "now": true,
+      "refresh_intervals": [
+        "5s",
+        "10s",
+        "30s",
+        "1m",
+        "5m",
+        "15m",
+        "30m",
+        "1h",
+        "2h",
+        "1d"
+      ],
+      "time_options": [
+        "5m",
+        "15m",
+        "1h",
+        "6h",
+        "12h",
+        "24h",
+        "2d",
+        "7d",
+        "30d"
+      ]
+    },
+    "templating": {
+      "list": []
+    },
+    "annotations": {
+      "list": []
+    },
+    "schemaVersion": 8,
+    "version": 0,
+    "links": [
+      {
+        "asDropdown": true,
+        "icon": "external link",
+        "keepTime": true,
+        "tags": [
+          "ambari_server"
+        ],
+        "title": "Ambari Server Stomp Stats",
+        "type": "dashboards"
+      }
+    ]
+}
\ No newline at end of file
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/metrics/system/impl/StompStatsMetricsSourceTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/metrics/system/impl/StompStatsMetricsSourceTest.java
new file mode 100644
index 0000000000..a7a09a3f76
--- /dev/null
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/metrics/system/impl/StompStatsMetricsSourceTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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
+ *
+ *     http://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.ambari.server.metrics.system.impl;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.apache.ambari.server.metrics.system.SingleMetric;
+import org.easymock.EasyMock;
+import org.junit.Test;
+import org.springframework.web.socket.config.WebSocketMessageBrokerStats;
+
+public class StompStatsMetricsSourceTest {
+    @Test
+    public void testStatsMetrics() {
+        String webStat = "[1 current WS(2)-HttpStream(3)-HttpPoll(4), 5 total, 
6 closed abnormally (7 connect failure, 8 send limit, 9 transport error)]";
+        String poolStat = "[pool size = 10, active threads = 20, queued tasks 
= 30, completed tasks = 40";
+        String stompSubProtocolStat = "[1 connect, 2 connected, 3 disconnect]";
+        Double[] webStatArray = { 1D, 2D, 3D, 4D, 5D, 6D, 7D, 8D, 9D };
+        Double[] poolStatArray = { 10D, 20D, 30D, 40D };
+        Double[] stompSubProtocolStatArray = { 1D, 2D, 3D };
+
+        WebSocketMessageBrokerStats apiStompStatsMock = 
createNiceMock(WebSocketMessageBrokerStats.class);
+        WebSocketMessageBrokerStats agentStompStatsMock = 
createNiceMock(WebSocketMessageBrokerStats.class);
+
+        StompStatsMetricsSource stompStatsMetricsSource = new 
StompStatsMetricsSource();
+
+        stompStatsMetricsSource.setApiStompStats(apiStompStatsMock);
+        stompStatsMetricsSource.setAgentStompStats(agentStompStatsMock);
+
+        
EasyMock.expect(apiStompStatsMock.getWebSocketSessionStatsInfo()).andReturn(webStat).anyTimes();
+        
EasyMock.expect(apiStompStatsMock.getStompSubProtocolStatsInfo()).andReturn(stompSubProtocolStat).anyTimes();
+        
EasyMock.expect(apiStompStatsMock.getClientInboundExecutorStatsInfo()).andReturn(poolStat).anyTimes();
+        
EasyMock.expect(apiStompStatsMock.getClientOutboundExecutorStatsInfo()).andReturn(poolStat).anyTimes();
+        
EasyMock.expect(apiStompStatsMock.getSockJsTaskSchedulerStatsInfo()).andReturn(poolStat).anyTimes();
+
+        
EasyMock.expect(agentStompStatsMock.getWebSocketSessionStatsInfo()).andReturn(webStat).anyTimes();
+        
EasyMock.expect(agentStompStatsMock.getStompSubProtocolStatsInfo()).andReturn(stompSubProtocolStat).anyTimes();
+        
EasyMock.expect(agentStompStatsMock.getClientInboundExecutorStatsInfo()).andReturn(poolStat).anyTimes();
+        
EasyMock.expect(agentStompStatsMock.getClientOutboundExecutorStatsInfo()).andReturn(poolStat).anyTimes();
+        
EasyMock.expect(agentStompStatsMock.getSockJsTaskSchedulerStatsInfo()).andReturn(poolStat).anyTimes();
+
+        EasyMock.replay(apiStompStatsMock);
+        EasyMock.replay(agentStompStatsMock);
+
+        List<SingleMetric> metricList = 
stompStatsMetricsSource.getStompStatMetrics();
+
+        for (int i = 0; i < StompStatsMetricsSource.webSocketMetrics.length; 
i++) {
+            assertEquals(webStatArray[i], getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[0]
+                    + ".websocket." + 
StompStatsMetricsSource.webSocketMetrics[i]), 0.00);
+            assertEquals(webStatArray[i], getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[1]
+                    + ".websocket." + 
StompStatsMetricsSource.webSocketMetrics[i]), 0.00);
+        }
+
+        for (int i = 0; i < 
StompStatsMetricsSource.stompSubProtocolMetrics.length; i++) {
+            assertEquals(stompSubProtocolStatArray[i],
+                    getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[0] + ".stomp_sub_protocol."
+                            + 
StompStatsMetricsSource.stompSubProtocolMetrics[i]),
+                    0.00);
+            assertEquals(stompSubProtocolStatArray[i],
+                    getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[1] + ".stomp_sub_protocol."
+                            + 
StompStatsMetricsSource.stompSubProtocolMetrics[i]),
+                    0.00);
+        }
+        for (int i = 0; i < StompStatsMetricsSource.poolMetrics.length; i++) {
+            assertEquals(poolStatArray[i], getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[0]
+                    + ".inbound_channel." + 
StompStatsMetricsSource.poolMetrics[i]), 0.00);
+            assertEquals(poolStatArray[i], getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[1]
+                    + ".inbound_channel." + 
StompStatsMetricsSource.poolMetrics[i]), 0.00);
+        }
+        for (int i = 0; i < StompStatsMetricsSource.poolMetrics.length; i++) {
+            assertEquals(poolStatArray[i], getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[0]
+                    + ".outbound_channel." + 
StompStatsMetricsSource.poolMetrics[i]), 0.00);
+            assertEquals(poolStatArray[i], getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[1]
+                    + ".outbound_channel." + 
StompStatsMetricsSource.poolMetrics[i]), 0.00);
+        }
+
+        for (int i = 0; i < StompStatsMetricsSource.poolMetrics.length; i++) {
+            assertEquals(poolStatArray[i], getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[0]
+                    + ".sockJsScheduler." + 
StompStatsMetricsSource.poolMetrics[i]), 0.00);
+            assertEquals(poolStatArray[i], getMetricValues(metricList, 
StompStatsMetricsSource.metricsTypes[1]
+                    + ".sockJsScheduler." + 
StompStatsMetricsSource.poolMetrics[i]), 0.00);
+        }
+    }
+
+    private double getMetricValues(List<SingleMetric> metricList, String 
metricName) {
+        for (SingleMetric metric : metricList) {
+            if (metric.getMetricName().equals(metricName)) {
+                return metric.getValue();
+            }
+        }
+        throw new RuntimeException("Metric " + metricName + " not found");
+    }
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to