You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by av...@apache.org on 2016/12/14 19:24:40 UTC

ambari git commit: AMBARI-17591 : Collect JVM Heap, GC and thread pool metrics from Ambari Server and push to AMS (Li-Wei Tseng via avijayan)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.5 0d2ceecd2 -> 98c5d9844


AMBARI-17591 : Collect JVM Heap, GC and thread pool metrics from Ambari Server and push to AMS (Li-Wei Tseng via avijayan)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/98c5d984
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/98c5d984
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/98c5d984

Branch: refs/heads/branch-2.5
Commit: 98c5d98442099799f961736b7f7264e6f84b5858
Parents: 0d2ceec
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Wed Dec 14 10:51:46 2016 -0800
Committer: Aravindan Vijayan <av...@hortonworks.com>
Committed: Wed Dec 14 10:51:46 2016 -0800

----------------------------------------------------------------------
 ambari-server/conf/unix/metrics.properties      |  31 +
 ambari-server/pom.xml                           |  10 +
 .../ambari/server/controller/AmbariServer.java  |  13 +
 .../server/controller/ControllerModule.java     |   4 +
 .../server/metrics/system/AmbariMetricSink.java |  34 +
 .../server/metrics/system/MetricsService.java   |  26 +
 .../server/metrics/system/MetricsSource.java    |  25 +
 .../system/impl/AbstractMetricsSource.java      |  41 ++
 .../system/impl/AmbariMetricSinkImpl.java       | 168 +++++
 .../metrics/system/impl/Configuration.java      |  83 +++
 .../metrics/system/impl/JvmMetricsSource.java   |  75 ++
 .../metrics/system/impl/MetricsServiceImpl.java | 168 +++++
 .../default/grafana-ambari-server.json          | 691 +++++++++++++++++++
 13 files changed, 1369 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/conf/unix/metrics.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/metrics.properties b/ambari-server/conf/unix/metrics.properties
new file mode 100644
index 0000000..5f01e39
--- /dev/null
+++ b/ambari-server/conf/unix/metrics.properties
@@ -0,0 +1,31 @@
+# Copyright 2011 The Apache Software Foundation
+#
+# 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.
+
+
+# Metrics sources info
+metrics.sources=jvm
+
+# Source interval determines how often the metric is sent to sink. Its unit is in seconds
+source.jvm.interval=5
+source.jvm.class=org.apache.ambari.server.metrics.system.impl.JvmMetricsSource
+
+#source.database.interval=10
+#source.database.class=org.apache.ambari.server.metrics.system.impl.DbMetricSource
+
+# Sink frequency determines how often the sink publish the metrics from buffer to AMS.
+sink.frequency=10
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index 6307a14..fcb6fcd 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -1471,6 +1471,16 @@
       <artifactId>jna</artifactId>
       <version>4.1.0</version>
     </dependency>
+    <dependency>
+      <groupId>io.dropwizard.metrics</groupId>
+      <artifactId>metrics-core</artifactId>
+      <version>3.1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>io.dropwizard.metrics</groupId>
+      <artifactId>metrics-jvm</artifactId>
+      <version>3.1.0</version>
+    </dependency>
   </dependencies>
 
   <pluginRepositories>

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
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 23f9dcc..dcc56c9 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
@@ -75,6 +75,7 @@ import org.apache.ambari.server.controller.internal.UserPrivilegeResourceProvide
 import org.apache.ambari.server.controller.internal.ViewPermissionResourceProvider;
 import org.apache.ambari.server.controller.metrics.ThreadPoolEnabledPropertyProvider;
 import org.apache.ambari.server.controller.utilities.KerberosChecker;
+import org.apache.ambari.server.metrics.system.MetricsService;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.PersistenceType;
 import org.apache.ambari.server.orm.dao.BlueprintDAO;
@@ -160,6 +161,10 @@ import com.google.inject.persist.Transactional;
 import com.sun.jersey.spi.container.servlet.ServletContainer;
 
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+
 @Singleton
 public class AmbariServer {
   public static final String VIEWS_URL_PATTERN = "/api/v1/views/*";
@@ -543,6 +548,14 @@ public class AmbariServer {
        */
       server.start();
 
+      // TODO, start every other tread.
+      final ExecutorService executor = Executors.newSingleThreadExecutor();
+      MetricsService metricsService = injector.getInstance(
+              MetricsService.class);
+      metricsService.init();
+      executor.submit(metricsService);
+      LOG.info("********* Started Ambari Metrics **********");
+
       serverForAgent.start();
       LOG.info("********* Started Server **********");
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 2c4bf5f..053031b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -72,6 +72,8 @@ import org.apache.ambari.server.hooks.users.UserCreatedEvent;
 import org.apache.ambari.server.hooks.users.UserHookService;
 import org.apache.ambari.server.metadata.CachedRoleCommandOrderProvider;
 import org.apache.ambari.server.metadata.RoleCommandOrderProvider;
+import org.apache.ambari.server.metrics.system.MetricsService;
+import org.apache.ambari.server.metrics.system.impl.MetricsServiceImpl;
 import org.apache.ambari.server.notifications.DispatchFactory;
 import org.apache.ambari.server.notifications.NotificationDispatcher;
 import org.apache.ambari.server.notifications.dispatchers.AmbariSNMPDispatcher;
@@ -379,6 +381,8 @@ public class ControllerModule extends AbstractModule {
     // factory to create LoggingRequestHelper instances for LogSearch integration
     bind(LoggingRequestHelperFactory.class).to(LoggingRequestHelperFactoryImpl.class);
 
+    bind(MetricsService.class).to(MetricsServiceImpl.class).in(Scopes.SINGLETON);
+
     requestStaticInjection(DatabaseConsistencyCheckHelper.class);
     requestStaticInjection(KerberosChecker.class);
     requestStaticInjection(AuthorizationHelper.class);

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/AmbariMetricSink.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/AmbariMetricSink.java b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/AmbariMetricSink.java
new file mode 100644
index 0000000..809176be
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/AmbariMetricSink.java
@@ -0,0 +1,34 @@
+/**
+ * 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.hadoop.metrics2.sink.ambari;
+
+package org.apache.ambari.server.metrics.system;
+
+import java.util.Map;
+
+public interface AmbariMetricSink {
+  /**
+   * initialize Collector URI and sink frequency to publish the metrics to AMS
+   **/
+  void init(String protocol, String collectorUri, int frequency);
+
+  /**
+  *  Publish metrics to Collector
+  **/
+  void publish(Map<String, Number> metricsMap);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/MetricsService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/MetricsService.java b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/MetricsService.java
new file mode 100644
index 0000000..23845c9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/MetricsService.java
@@ -0,0 +1,26 @@
+/**
+ * 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;
+
+public interface MetricsService extends Runnable {
+  /**
+   * Set up configuration
+   **/
+  void init();
+}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/MetricsSource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/MetricsSource.java b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/MetricsSource.java
new file mode 100644
index 0000000..cf10408
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/MetricsSource.java
@@ -0,0 +1,25 @@
+/**
+ * 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;
+
+public interface MetricsSource extends Runnable{
+  /**
+   * initialize sink
+   **/
+  void init(AmbariMetricSink sink);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AbstractMetricsSource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AbstractMetricsSource.java b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AbstractMetricsSource.java
new file mode 100644
index 0000000..58e2045
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AbstractMetricsSource.java
@@ -0,0 +1,41 @@
+/**
+ * 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 org.apache.ambari.server.metrics.system.AmbariMetricSink;
+import org.apache.ambari.server.metrics.system.MetricsSource;
+
+import java.util.Map;
+
+public abstract class AbstractMetricsSource implements MetricsSource {
+  protected AmbariMetricSink sink;
+
+  /**
+   *  Pass metrics sink to metrics source
+   **/
+  @Override
+  public void init(AmbariMetricSink sink) {
+      this.sink = sink;
+  }
+
+  /**
+   *  Get metrics at the instance
+   *  @return a map for metrics that maps metrics name to metrics value
+   **/
+  abstract public Map<String, Number> getMetrics();
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java
new file mode 100644
index 0000000..d42dbdf
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java
@@ -0,0 +1,168 @@
+/**
+ * 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.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ambari.server.metrics.system.AmbariMetricSink;
+import org.apache.commons.lang.ClassUtils;
+import org.apache.hadoop.metrics2.sink.timeline.AbstractTimelineMetricsSink;
+import org.apache.hadoop.metrics2.sink.timeline.TimelineMetric;
+import org.apache.hadoop.metrics2.sink.timeline.TimelineMetrics;
+
+import jline.internal.Log;
+
+public class AmbariMetricSinkImpl extends AbstractTimelineMetricsSink implements AmbariMetricSink {
+  private static final String APP_ID = "ambari_server";
+  private int timeoutSeconds = 10;
+  private String collectorProtocol;
+  private String collectorUri;
+  private String hostName;
+  private int counter = 0;
+  private int frequency;
+  private List<TimelineMetric> buffer = new ArrayList<>();
+  @Override
+  public void init(String protocol, String collectorUri, int frequency) {
+
+    /**
+     * Protocol is either HTTP or HTTPS, and the collectorURI is the domain name of the collector
+     * An example of the complete collector URI might be: http://c6403.ambari.org/ws/v1/timeline/metrics
+     */
+    this.frequency = frequency;
+    this.collectorProtocol = protocol;
+    this.collectorUri = getCollectorUri(collectorUri);
+
+    try {
+      hostName = InetAddress.getLocalHost().getHostName();
+    } catch (UnknownHostException e) {
+      Log.info("Error getting host address");
+    }
+  }
+
+  @Override
+  public void publish(Map<String, Number> metricsMap) {
+    List<TimelineMetric> metricsList =  createMetricsList(metricsMap);
+
+    if(counter > frequency) {
+      TimelineMetrics timelineMetrics = new TimelineMetrics();
+      timelineMetrics.setMetrics(buffer);
+
+      String connectUrl = collectorUri;
+      String jsonData = null;
+      try {
+        jsonData = mapper.writeValueAsString(timelineMetrics);
+      } catch (IOException e) {
+        LOG.error("Unable to parse metrics", e);
+      }
+      if (jsonData != null) {
+        emitMetricsJson(connectUrl, jsonData);
+      }
+      counter = 0;
+    } else {
+      buffer.addAll(metricsList);
+      counter++;
+    }
+
+  }
+
+
+  /**
+   * Get a pre-formatted URI for the collector
+   *
+   * @param host
+   */
+  @Override
+  protected String getCollectorUri(String host) {
+    return getCollectorProtocol() + "://" + host + WS_V1_TIMELINE_METRICS;
+  }
+
+  @Override
+  protected String getCollectorProtocol() {
+    return collectorProtocol;
+  }
+
+  @Override
+  protected String getCollectorPort() {
+    return null;
+  }
+
+  @Override
+  protected int getTimeoutSeconds() {
+    return timeoutSeconds;
+  }
+
+  /**
+   * Get the zookeeper quorum for the cluster used to find collector
+   *
+   * @return String "host1:port1,host2:port2"
+   */
+  @Override
+  protected String getZookeeperQuorum() {
+    return null;
+  }
+
+  /**
+   * Get pre-configured list of collectors available
+   *
+   * @return Collection<String> host1,host2
+   */
+  @Override
+  protected Collection<String> getConfiguredCollectorHosts() {
+    return null;
+  }
+
+  /**
+   * Get hostname used for calculating write shard.
+   *
+   * @return String "host1"
+   */
+  @Override
+  protected String getHostname() {
+    return hostName;
+  }
+
+  private List<TimelineMetric> createMetricsList(Map<String, Number> metricsMap) {
+    final List<TimelineMetric> metricsList = new ArrayList<>();
+    for (Map.Entry<String, Number> entry : metricsMap.entrySet()) {
+      final long currentTimeMillis = System.currentTimeMillis();
+      String metricsName = entry.getKey();
+      Number value = entry.getValue();
+      TimelineMetric metric = createTimelineMetric(currentTimeMillis, APP_ID, metricsName, value);
+      metricsList.add(metric);
+    }
+    return metricsList;
+  }
+
+  private TimelineMetric createTimelineMetric(long currentTimeMillis, String component, String attributeName,
+                                              Number attributeValue) {
+    TimelineMetric timelineMetric = new TimelineMetric();
+    timelineMetric.setMetricName(attributeName);
+    timelineMetric.setHostName(hostName);
+    timelineMetric.setAppId(component);
+    timelineMetric.setStartTime(currentTimeMillis);
+    timelineMetric.setType(ClassUtils.getShortCanonicalName(attributeValue, "Number"));
+    timelineMetric.getMetricValues().put(currentTimeMillis, attributeValue.doubleValue());
+    return timelineMetric;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/Configuration.java
new file mode 100644
index 0000000..705971f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/Configuration.java
@@ -0,0 +1,83 @@
+/**
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class Configuration {
+  public static final String CONFIG_FILE = "metrics.properties";
+
+  private static Logger LOG = LoggerFactory.getLogger(Configuration.class);
+  private Properties properties;
+
+  public Configuration() {
+      this(readConfigFile());
+  }
+
+  public Configuration(Properties properties) {
+      this.properties = properties;
+  }
+
+  private static Properties readConfigFile() {
+      Properties properties = new Properties();
+
+      //Get property file stream from classpath
+      InputStream inputStream = Configuration.class.getClassLoader().getResourceAsStream(CONFIG_FILE);
+
+      if (inputStream == null) {
+          throw new RuntimeException(CONFIG_FILE + " not found in classpath");
+      }
+
+      // load the properties
+      try {
+          properties.load(inputStream);
+          inputStream.close();
+      } catch (FileNotFoundException fnf) {
+          LOG.info("No configuration file " + CONFIG_FILE + " found in classpath.", fnf);
+      } catch (IOException ie) {
+          throw new IllegalArgumentException("Can't read configuration file " +
+                  CONFIG_FILE, ie);
+      }
+
+      return properties;
+  }
+
+  /**
+   * Get the property value for the given key.
+   *
+   * @return the property value
+   */
+  public String getProperty(String key) {
+    return properties.getProperty(key);
+  }
+
+  /**
+   * Get the property value for the given key.
+   *
+   * @return the property value
+   */
+  public String getProperty(String key, String defaultValue) {
+    return properties.getProperty(key, defaultValue);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/JvmMetricsSource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/JvmMetricsSource.java b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/JvmMetricsSource.java
new file mode 100644
index 0000000..a04ca43
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/JvmMetricsSource.java
@@ -0,0 +1,75 @@
+/**
+ * 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 com.codahale.metrics.Metric;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.MetricSet;
+import com.codahale.metrics.jvm.BufferPoolMetricSet;
+import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
+import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
+import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
+import org.apache.ambari.server.metrics.system.AmbariMetricSink;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.Map;
+
+public class JvmMetricsSource extends AbstractMetricsSource {
+  static final MetricRegistry registry = new MetricRegistry();
+  private static Logger LOG = LoggerFactory.getLogger(JvmMetricsSource.class);
+
+  @Override
+  public void init(AmbariMetricSink sink) {
+    super.init(sink);
+    registerAll("gc", new GarbageCollectorMetricSet(), registry);
+    registerAll("buffers", new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()), registry);
+    registerAll("memory", new MemoryUsageGaugeSet(), registry);
+    registerAll("threads", new ThreadStatesGaugeSet(), registry);
+  }
+
+  @Override
+  public void run() {
+    this.sink.publish(getMetrics());
+    LOG.info("********* Published system metrics to sink **********");
+  }
+
+
+  private void registerAll(String prefix, MetricSet metricSet, MetricRegistry registry) {
+    for (Map.Entry<String, Metric> entry : metricSet.getMetrics().entrySet()) {
+      if (entry.getValue() instanceof MetricSet) {
+        registerAll(prefix + "." + entry.getKey(), (MetricSet) entry.getValue(), registry);
+      } else {
+        registry.register(prefix + "." + entry.getKey(), entry.getValue());
+      }
+    }
+  }
+
+  @Override
+  public Map<String, Number> getMetrics() {
+    Map<String, Number> map = new HashMap<>();
+    for (String metricName : registry.getGauges().keySet()) {
+      if (metricName.equals("threads.deadlocks") ) continue;
+      Number value = (Number)registry.getGauges().get(metricName).getValue();
+      map.put(metricName, value);
+    }
+    return map;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsServiceImpl.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..1645ebf
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/MetricsServiceImpl.java
@@ -0,0 +1,168 @@
+/**
+ * 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 com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.internal.AbstractControllerResourceProvider;
+import org.apache.ambari.server.controller.internal.ServiceConfigVersionResourceProvider;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.metrics.system.AmbariMetricSink;
+import org.apache.ambari.server.metrics.system.MetricsService;
+import org.apache.ambari.server.security.authorization.internal.InternalAuthenticationToken;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+@Singleton
+public class MetricsServiceImpl implements MetricsService {
+  private static Logger LOG = LoggerFactory.getLogger(MetricsServiceImpl.class);
+  private Map<String, AbstractMetricsSource> sources = new HashMap<>();
+  private AmbariMetricSink sink = new AmbariMetricSinkImpl();
+  private String collectorUri = "";
+  private String collectorProtocol = "";
+  private Configuration configuration;
+
+  @Inject
+  AmbariManagementController amc;
+
+  @Override
+  public void init() {
+    try {
+      configuration = new Configuration();
+      if (collectorUri.isEmpty() || collectorProtocol.isEmpty()) {
+        setCollectorUri();
+      }
+      configureSourceAndSink();
+    } catch (Exception e) {
+      LOG.info("Error initializing MetricsService", e);
+    }
+
+  }
+  @Override
+  public void run() {
+    final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
+    for (Map.Entry<String, AbstractMetricsSource> entry : sources.entrySet()) {
+      publishMetrics(executor, entry);
+    }
+  }
+
+
+  private void setCollectorUri() {
+    InternalAuthenticationToken authenticationToken = new InternalAuthenticationToken("admin");
+    authenticationToken.setAuthenticated(true);
+    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+    Clusters clusters = amc.getClusters();
+    for (Map.Entry<String, Cluster> kv : clusters.getClusters().entrySet()) {
+      String clusterName = kv.getKey();
+      Resource.Type type = Resource.Type.ServiceConfigVersion;
+
+      Set<String> propertyIds = new HashSet<String>();
+      propertyIds.add(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_CONFIGURATIONS_PROPERTY_ID);
+
+      Predicate predicate = new PredicateBuilder().property(
+        ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_CLUSTER_NAME_PROPERTY_ID).equals(clusterName).and().property(
+        ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_SERVICE_NAME_PROPERTY_ID).equals("AMBARI_METRICS").and().property(
+        ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_IS_CURRENT_PROPERTY_ID).equals("true").toPredicate();
+
+      Request request = PropertyHelper.getReadRequest(propertyIds);
+
+      ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        amc);
+
+      try {
+        Set<Resource> resources = provider.getResources(request, predicate);
+
+        // get collector uri
+        for (Resource resource : resources) {
+          if (resource != null) {
+            ArrayList<LinkedHashMap<Object, Object>> configs = (ArrayList<LinkedHashMap<Object, Object>>)
+              resource.getPropertyValue(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_CONFIGURATIONS_PROPERTY_ID);
+            for (LinkedHashMap<Object, Object> config : configs) {
+              if (config != null && config.get("type").equals("ams-site")) {
+                TreeMap<Object, Object> properties = (TreeMap<Object, Object>) config.get("properties");
+                collectorUri = (String) properties.get("timeline.metrics.service.webapp.address");
+                String which_protocol = (String) properties.get("timeline.metrics.service.http.policy");
+                collectorProtocol = which_protocol.equals("HTTP_ONLY") ? "http" : "https";
+                break;
+              }
+            }
+          }
+        }
+      } catch (Exception e) {
+        LOG.info("Throwing exception when retrieving Collector URI", e);
+      }
+    }
+  }
+
+  private void configureSourceAndSink() {
+    try {
+      LOG.info("********* Configuring Ambari Metrics Sink and Source**********");
+      int frequency = Integer.parseInt(configuration.getProperty("sink.frequency", "10")); // default value 10
+      sink.init(collectorProtocol, collectorUri, frequency);
+      String[] sourceNames = configuration.getProperty("metrics.sources").split(",");
+      for (String sourceName: sourceNames) {
+        String className = configuration.getProperty("source." + sourceName + ".class");
+        Class t = Class.forName(className);
+        AbstractMetricsSource src = (AbstractMetricsSource)t.newInstance();
+        src.init(sink);
+        sources.put(sourceName, src);
+      }
+    }
+    catch (Exception e) {
+      LOG.info("Throwing exception when registering metric sink and source", e);
+    }
+  }
+
+  private void publishMetrics(ScheduledExecutorService executor, Map.Entry<String, AbstractMetricsSource> entry) {
+    String className = entry.getKey();
+    AbstractMetricsSource source = entry.getValue();
+    String interval = "source." + className + ".interval";
+    int duration = Integer.parseInt(configuration.getProperty(interval, "5")); // default value 5
+    try {
+      executor.scheduleWithFixedDelay(source, 0, duration, TimeUnit.SECONDS);
+
+    } catch (Exception e) {
+      LOG.info("Throwing exception when failing scheduling source", e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/98c5d984/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/files/grafana-dashboards/default/grafana-ambari-server.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/files/grafana-dashboards/default/grafana-ambari-server.json b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/files/grafana-dashboards/default/grafana-ambari-server.json
new file mode 100644
index 0000000..de66e83
--- /dev/null
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/files/grafana-dashboards/default/grafana-ambari-server.json
@@ -0,0 +1,691 @@
+{
+  "id": null,
+  "title": "Ambari Server",
+  "originalTitle": "Ambari Server",
+  "tags": [
+    "ambari"
+  ],
+  "style": "dark",
+  "timezone": "browser",
+  "editable": true,
+  "hideControls": false,
+  "sharedCrosshair": false,
+  "rows": [
+    {
+      "collapse": false,
+      "editable": true,
+      "height": "25px",
+      "panels": [
+        {
+          "content": "<h4 align=\"center\">Metrics to see the overall status for Ambari Server. Click on each row title to expand on demand to look at various metrics. </h4>\n<h6 style=\"color:red;\" align=\"center\">This dashboard is managed by Ambari.  You may lose any changes made to this dashboard.  If you want to customize, make your own copy.</h6>",
+          "editable": true,
+          "error": false,
+          "id": 10,
+          "isNew": true,
+          "links": [],
+          "mode": "html",
+          "span": 12,
+          "style": {},
+          "title": "",
+          "type": "text"
+        }
+      ],
+      "title": "New row"
+    },
+    {
+      "collapse": false,
+      "editable": true,
+      "height": "250px",
+      "panels": [
+        {
+          "aliasColors": {},
+          "bars": false,
+          "datasource": null,
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "grid": {
+            "leftLogBase": 1,
+            "leftMax": null,
+            "leftMin": null,
+            "rightLogBase": 1,
+            "rightMax": null,
+            "rightMin": null,
+            "threshold1": null,
+            "threshold1Color": "rgba(216, 200, 27, 0.27)",
+            "threshold2": null,
+            "threshold2Color": "rgba(234, 112, 112, 0.22)"
+          },
+          "id": 3,
+          "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": "max",
+              "alias": "MemHeapMax",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "memory.heap.max",
+              "precision": "default",
+              "refId": "A",
+              "seriesAggregator": "none",
+              "transform": "none"
+            },
+            {
+              "aggregator": "max",
+              "alias": "MemHeapUsed",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "memory.heap.used",
+              "precision": "default",
+              "refId": "B",
+              "seriesAggregator": "none",
+              "transform": "none"
+            },
+            {
+              "aggregator": "max",
+              "alias": "MemHeapCommitted",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "memory.heap.committed",
+              "precision": "default",
+              "refId": "C",
+              "seriesAggregator": "none",
+              "transform": "none"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Heap Usage",
+          "tooltip": {
+            "shared": true,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "x-axis": true,
+          "y-axis": true,
+          "y_formats": [
+            "bytes",
+            "short"
+          ]
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "datasource": null,
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "grid": {
+            "leftLogBase": 1,
+            "leftMax": null,
+            "leftMin": null,
+            "rightLogBase": 1,
+            "rightMax": null,
+            "rightMin": null,
+            "threshold1": null,
+            "threshold1Color": "rgba(216, 200, 27, 0.27)",
+            "threshold2": null,
+            "threshold2Color": "rgba(234, 112, 112, 0.22)"
+          },
+          "id": 4,
+          "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": "max",
+              "alias": "MemNonHeapMax",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "memory.non-heap.max",
+              "precision": "default",
+              "refId": "A",
+              "seriesAggregator": "none",
+              "transform": "none"
+            },
+            {
+              "aggregator": "none",
+              "alias": "MemNonHeapUsed",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "memory.non-heap.used",
+              "precision": "default",
+              "refId": "B",
+              "seriesAggregator": "none",
+              "transform": "none"
+            },
+            {
+              "aggregator": "none",
+              "alias": "MemNonHeapCommitted",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "memory.non-heap.committed",
+              "precision": "default",
+              "refId": "C",
+              "seriesAggregator": "none",
+              "transform": "none"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Off-Heap Usage",
+          "tooltip": {
+            "shared": true,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "x-axis": true,
+          "y-axis": true,
+          "y_formats": [
+            "bytes",
+            "short"
+          ]
+        }
+      ],
+      "showTitle": true,
+      "title": "JVM - Memory Pressure"
+    },
+    {
+      "collapse": true,
+      "editable": true,
+      "height": "250px",
+      "panels": [
+        {
+          "aliasColors": {},
+          "bars": false,
+          "datasource": null,
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "grid": {
+            "leftLogBase": 1,
+            "leftMax": null,
+            "leftMin": null,
+            "rightLogBase": 1,
+            "rightMax": null,
+            "rightMin": null,
+            "threshold1": null,
+            "threshold1Color": "rgba(216, 200, 27, 0.27)",
+            "threshold2": null,
+            "threshold2Color": "rgba(234, 112, 112, 0.22)"
+          },
+          "id": 6,
+          "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": "avg",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "gc.ParNew.count",
+              "precision": "default",
+              "refId": "A",
+              "seriesAggregator": "none",
+              "transform": "rate"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "GC Count Par New /s",
+          "tooltip": {
+            "shared": true,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "x-axis": true,
+          "y-axis": true,
+          "y_formats": [
+            "short",
+            "short"
+          ]
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "datasource": null,
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "grid": {
+            "leftLogBase": 1,
+            "leftMax": null,
+            "leftMin": null,
+            "rightLogBase": 1,
+            "rightMax": null,
+            "rightMin": null,
+            "threshold1": null,
+            "threshold1Color": "rgba(216, 200, 27, 0.27)",
+            "threshold2": null,
+            "threshold2Color": "rgba(234, 112, 112, 0.22)"
+          },
+          "id": 5,
+          "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": "avg",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "gc.ParNew.time",
+              "precision": "default",
+              "refId": "A",
+              "seriesAggregator": "none",
+              "transform": "rate"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "GC Time Par New /s",
+          "tooltip": {
+            "shared": true,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "x-axis": true,
+          "y-axis": true,
+          "y_formats": [
+            "short",
+            "short"
+          ]
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "datasource": null,
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "grid": {
+            "leftLogBase": 1,
+            "leftMax": null,
+            "leftMin": null,
+            "rightLogBase": 1,
+            "rightMax": null,
+            "rightMin": null,
+            "threshold1": null,
+            "threshold1Color": "rgba(216, 200, 27, 0.27)",
+            "threshold2": null,
+            "threshold2Color": "rgba(234, 112, 112, 0.22)"
+          },
+          "id": 7,
+          "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": "max",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "gc.ConcurrentMarkSweep.count",
+              "precision": "default",
+              "refId": "A",
+              "seriesAggregator": "none",
+              "transform": "rate"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "GC Count CMS /s",
+          "tooltip": {
+            "shared": true,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "x-axis": true,
+          "y-axis": true,
+          "y_formats": [
+            "short",
+            "short"
+          ]
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "datasource": null,
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "grid": {
+            "leftLogBase": 1,
+            "leftMax": null,
+            "leftMin": null,
+            "rightLogBase": 1,
+            "rightMax": null,
+            "rightMin": null,
+            "threshold1": null,
+            "threshold1Color": "rgba(216, 200, 27, 0.27)",
+            "threshold2": null,
+            "threshold2Color": "rgba(234, 112, 112, 0.22)"
+          },
+          "id": 8,
+          "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": "avg",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "gc.ConcurrentMarkSweep.time",
+              "precision": "default",
+              "refId": "A",
+              "seriesAggregator": "none",
+              "transform": "rate"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "GC Time CMS /s",
+          "tooltip": {
+            "shared": true,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "x-axis": true,
+          "y-axis": true,
+          "y_formats": [
+            "short",
+            "short"
+          ]
+        }
+      ],
+      "showTitle": true,
+      "title": "JVM - GC Count"
+    },
+    {
+      "collapse": true,
+      "editable": true,
+      "height": "250px",
+      "panels": [
+        {
+          "aliasColors": {},
+          "bars": false,
+          "datasource": null,
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "grid": {
+            "leftLogBase": 1,
+            "leftMax": null,
+            "leftMin": null,
+            "rightLogBase": 1,
+            "rightMax": null,
+            "rightMin": null,
+            "threshold1": null,
+            "threshold1Color": "rgba(216, 200, 27, 0.27)",
+            "threshold2": null,
+            "threshold2Color": "rgba(234, 112, 112, 0.22)"
+          },
+          "id": 9,
+          "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": 12,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "aggregator": "max",
+              "alias": "Total",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "threads.count",
+              "precision": "default",
+              "refId": "A",
+              "seriesAggregator": "none",
+              "transform": "none"
+            },
+            {
+              "aggregator": "max",
+              "alias": "Daemon",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "threads.daemon.count",
+              "precision": "default",
+              "refId": "B",
+              "seriesAggregator": "none",
+              "transform": "none"
+            },
+            {
+              "aggregator": "max",
+              "alias": "Deadlock",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "threads.deadlock.count",
+              "precision": "default",
+              "refId": "C",
+              "seriesAggregator": "none",
+              "transform": "none"
+            },
+            {
+              "aggregator": "max",
+              "alias": "Blocked",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "threads.blocked.count",
+              "precision": "default",
+              "refId": "D",
+              "seriesAggregator": "none",
+              "transform": "none"
+            },
+            {
+              "aggregator": "max",
+              "alias": "Runnable",
+              "app": "ambari_server",
+              "downsampleAggregator": "avg",
+              "errors": {},
+              "metric": "threads.runnable.count",
+              "precision": "default",
+              "refId": "E",
+              "seriesAggregator": "none",
+              "transform": "none"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Thread Count",
+          "tooltip": {
+            "shared": true,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "x-axis": true,
+          "y-axis": true,
+          "y_formats": [
+            "short",
+            "short"
+          ]
+        }
+      ],
+      "showTitle": true,
+      "title": "JVM - Thread Count"
+    }
+  ],
+  "time": {
+    "from": "now-6h",
+    "to": "now"
+  },
+  "timepicker": {
+    "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": []
+  },
+  "refresh": false,
+  "schemaVersion": 8,
+  "version": 1,
+  "links": []
+}
\ No newline at end of file