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

ignite git commit: IGNITE-6867 Implement new JMX metrics for topology monitoring

Repository: ignite
Updated Branches:
  refs/heads/master 07ec8b00d -> 010d02b89


IGNITE-6867 Implement new JMX metrics for topology monitoring

Signed-off-by: Anton Vinogradov <av...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/010d02b8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/010d02b8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/010d02b8

Branch: refs/heads/master
Commit: 010d02b89fd440cfa6fbe5f24dd5258e440c467a
Parents: 07ec8b0
Author: Pereslegin Pavel <sb...@mail.ca.sbrf.ru>
Authored: Fri Nov 24 15:35:02 2017 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Fri Nov 24 15:35:02 2017 +0300

----------------------------------------------------------------------
 .../ClusterLocalNodeMetricsMXBeanImpl.java      |   4 +-
 .../internal/ClusterMetricsMXBeanImpl.java      |  71 ++++-
 .../apache/ignite/internal/IgniteKernal.java    |  21 +-
 .../mxbean/ClusterLocalNodeMetricsMXBean.java   | 257 ++++++++++++++++
 .../ignite/mxbean/ClusterMetricsMXBean.java     | 296 ++++---------------
 .../internal/ClusterNodeMetricsSelfTest.java    | 115 +++++++
 6 files changed, 519 insertions(+), 245 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/010d02b8/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java
index 263c20a..84079c3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/ClusterLocalNodeMetricsMXBeanImpl.java
@@ -19,12 +19,12 @@ package org.apache.ignite.internal;
 
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.mxbean.ClusterMetricsMXBean;
+import org.apache.ignite.mxbean.ClusterLocalNodeMetricsMXBean;
 
 /**
  * Local node metrics MBean.
  */
-public class ClusterLocalNodeMetricsMXBeanImpl implements ClusterMetricsMXBean {
+public class ClusterLocalNodeMetricsMXBeanImpl implements ClusterLocalNodeMetricsMXBean {
     /** Grid node. */
     private final ClusterNode node;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/010d02b8/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java
index de4e405..e3c75c6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/ClusterMetricsMXBeanImpl.java
@@ -17,8 +17,13 @@
 
 package org.apache.ignite.internal;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import org.apache.ignite.cluster.ClusterGroup;
 import org.apache.ignite.cluster.ClusterMetrics;
+import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.mxbean.ClusterMetricsMXBean;
 
@@ -297,7 +302,6 @@ public class ClusterMetricsMXBeanImpl implements ClusterMetricsMXBean {
         return metrics().getTotalJobsExecutionTime();
     }
 
-
     /** {@inheritDoc} */
     @Override public long getTotalIdleTime() {
         return metrics().getTotalIdleTime();
@@ -354,6 +358,71 @@ public class ClusterMetricsMXBeanImpl implements ClusterMetricsMXBean {
     }
 
     /** {@inheritDoc} */
+    @Override public int getTotalServerNodes() {
+        return cluster.forServers().nodes().size();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getTotalClientNodes() {
+        return cluster.forClients().nodes().size();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getTopologyVersion() {
+        return cluster.ignite().cluster().topologyVersion();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int countNodes(String attrName, String attrVal, boolean srv, boolean client) {
+        int cnt = 0;
+
+        for (ClusterNode node : nodesList(srv, client)) {
+            Object val = node.attribute(attrName);
+
+            if (val != null && val.toString().equals(attrVal))
+                ++cnt;
+        }
+
+        return cnt;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Map<Object, Integer> groupNodes(String attrName, boolean srv, boolean client) {
+        Map<Object, Integer> attrGroups = new HashMap<>();
+
+        for (ClusterNode node : nodesList(srv, client)) {
+            Object attrVal = node.attribute(attrName);
+
+            if (attrVal != null) {
+                Integer cnt = attrGroups.get(attrVal);
+
+                attrGroups.put(attrVal, cnt == null ? 1 : ++cnt);
+            }
+        }
+
+        return attrGroups;
+    }
+
+    /**
+     * Get list with the specified node types.
+     *
+     * @param srv {@code True} to include server nodes.
+     * @param client {@code True} to include client nodes.
+     * @return List with the specified node types.
+     */
+    private List<ClusterNode> nodesList(boolean srv, boolean client) {
+        List<ClusterNode> nodes = new ArrayList<>();
+
+        if (srv)
+            nodes.addAll(cluster.forServers().nodes());
+
+        if (client)
+            nodes.addAll(cluster.forClients().nodes());
+
+        return nodes;
+    }
+
+    /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(ClusterMetricsMXBeanImpl.class, this);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/010d02b8/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index d3793ae..f29b994 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -182,6 +182,7 @@ import org.apache.ignite.lifecycle.LifecycleBean;
 import org.apache.ignite.lifecycle.LifecycleEventType;
 import org.apache.ignite.marshaller.MarshallerExclusions;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
+import org.apache.ignite.mxbean.ClusterLocalNodeMetricsMXBean;
 import org.apache.ignite.mxbean.ClusterMetricsMXBean;
 import org.apache.ignite.mxbean.IgniteMXBean;
 import org.apache.ignite.mxbean.StripedExecutorMXBean;
@@ -1704,27 +1705,29 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
      * Register instance of ClusterMetricsMBean.
      *
      * @param mbean MBean instance to register.
+     * @param clazz MBean interface to register.
+     * @param <T> MBean type.
      * @throws IgniteCheckedException If registration failed.
      */
-    private ObjectName registerClusterMetricsMBean(ClusterMetricsMXBean mbean) throws IgniteCheckedException {
+    private <T> ObjectName registerClusterMetricsMBean(T mbean, Class<T> clazz) throws IgniteCheckedException {
         if(U.IGNITE_MBEANS_DISABLED)
             return null;
 
-        ObjectName objectName;
+        ObjectName objName;
 
         try {
-            objectName = U.registerMBean(
+            objName = U.registerMBean(
                 cfg.getMBeanServer(),
                 cfg.getIgniteInstanceName(),
                 "Kernal",
                 mbean.getClass().getSimpleName(),
                 mbean,
-                ClusterMetricsMXBean.class);
+                clazz);
 
             if (log.isDebugEnabled())
-                log.debug("Registered MBean: " + objectName);
+                log.debug("Registered MBean: " + objName);
 
-            return objectName;
+            return objName;
         }
         catch (JMException e) {
             throw new IgniteCheckedException("Failed to register MBean: " + mbean.getClass().getSimpleName(), e);
@@ -1733,8 +1736,10 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
 
     /** @throws IgniteCheckedException If registration failed. */
     private void registerClusterMetricsMBeans() throws IgniteCheckedException {
-        locNodeMBean = registerClusterMetricsMBean(new ClusterLocalNodeMetricsMXBeanImpl(ctx.discovery().localNode()));
-        allNodesMBean = registerClusterMetricsMBean(new ClusterMetricsMXBeanImpl(cluster()));
+        locNodeMBean = registerClusterMetricsMBean(new ClusterLocalNodeMetricsMXBeanImpl(ctx.discovery().localNode()),
+            ClusterLocalNodeMetricsMXBean.class);
+        allNodesMBean = registerClusterMetricsMBean(new ClusterMetricsMXBeanImpl(cluster()),
+            ClusterMetricsMXBean.class);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/010d02b8/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterLocalNodeMetricsMXBean.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterLocalNodeMetricsMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterLocalNodeMetricsMXBean.java
new file mode 100644
index 0000000..7e3ced2
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterLocalNodeMetricsMXBean.java
@@ -0,0 +1,257 @@
+/*
+ * 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.ignite.mxbean;
+
+import org.apache.ignite.cluster.ClusterMetrics;
+
+/**
+ * MBean for local node metrics.
+ */
+@MXBeanDescription("MBean that provides access to all local node metrics.")
+public interface ClusterLocalNodeMetricsMXBean extends ClusterMetrics {
+    /** {@inheritDoc} */
+    @MXBeanDescription("Last update time of this node metrics.")
+    public long getLastUpdateTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Maximum number of jobs that ever ran concurrently on this node.")
+    public int getMaximumActiveJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Number of currently active jobs concurrently executing on the node.")
+    public int getCurrentActiveJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Average number of active jobs concurrently executing on the node.")
+    public float getAverageActiveJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Maximum number of waiting jobs this node had.")
+    public int getMaximumWaitingJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Number of queued jobs currently waiting to be executed.")
+    public int getCurrentWaitingJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Average number of waiting jobs this node had queued.")
+    public float getAverageWaitingJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Maximum number of jobs rejected at once during a single collision resolution operation.")
+    public int getMaximumRejectedJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Number of jobs rejected after more recent collision resolution operation.")
+    public int getCurrentRejectedJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Average number of jobs this node rejects during collision resolution operations.")
+    public float getAverageRejectedJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription(
+        "Total number of jobs this node rejects during collision resolution operations since node startup.")
+    public int getTotalRejectedJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Maximum number of cancelled jobs this node ever had running concurrently.")
+    public int getMaximumCancelledJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Number of cancelled jobs that are still running.")
+    public int getCurrentCancelledJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Average number of cancelled jobs this node ever had running concurrently.")
+    public float getAverageCancelledJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Total number of cancelled jobs since node startup.")
+    public int getTotalCancelledJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Total number of jobs handled by the node.")
+    public int getTotalExecutedJobs();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Total time all finished jobs takes to execute on the node.")
+    public long getTotalJobsExecutionTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Maximum time a job ever spent waiting in a queue to be executed.")
+    public long getMaximumJobWaitTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Current wait time of oldest job.")
+    public long getCurrentJobWaitTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Average time jobs spend waiting in the queue to be executed.")
+    public double getAverageJobWaitTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Time it took to execute the longest job on the node.")
+    public long getMaximumJobExecuteTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Longest time a current job has been executing for.")
+    public long getCurrentJobExecuteTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Average time a job takes to execute on the node.")
+    public double getAverageJobExecuteTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Total number of tasks handled by the node.")
+    public int getTotalExecutedTasks();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Total time this node spent executing jobs.")
+    public long getTotalBusyTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Total time this node spent idling (not executing any jobs).")
+    public long getTotalIdleTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Time this node spend idling since executing last job.")
+    public long getCurrentIdleTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Percentage of time this node is busy executing jobs vs. idling.")
+    public float getBusyTimePercentage();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Percentage of time this node is idling vs. executing jobs.")
+    public float getIdleTimePercentage();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The number of CPUs available to the Java Virtual Machine.")
+    public int getTotalCpus();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The system load average; or a negative value if not available.")
+    public double getCurrentCpuLoad();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Average of CPU load values over all metrics kept in the history.")
+    public double getAverageCpuLoad();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Average time spent in CG since the last update.")
+    public double getCurrentGcCpuLoad();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The initial size of memory in bytes; -1 if undefined.")
+    public long getHeapMemoryInitialized();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Current heap size that is used for object allocation.")
+    public long getHeapMemoryUsed();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The amount of committed memory in bytes.")
+    public long getHeapMemoryCommitted();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The maximum amount of memory in bytes; -1 if undefined.")
+    public long getHeapMemoryMaximum();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The total amount of memory in bytes; -1 if undefined.")
+    public long getHeapMemoryTotal();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The initial size of memory in bytes; -1 if undefined.")
+    public long getNonHeapMemoryInitialized();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Current non-heap memory size that is used by Java VM.")
+    public long getNonHeapMemoryUsed();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Amount of non-heap memory in bytes that is committed for the JVM to use.")
+    public long getNonHeapMemoryCommitted();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Maximum amount of non-heap memory in bytes that can " +
+        "be used for memory management. -1 if undefined.")
+    public long getNonHeapMemoryMaximum();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Total amount of non-heap memory in bytes that can " +
+        "be used for memory management. -1 if undefined.")
+    public long getNonHeapMemoryTotal();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Uptime of the JVM in milliseconds.")
+    public long getUpTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Start time of the JVM in milliseconds.")
+    public long getStartTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Current number of live threads.")
+    public int getCurrentThreadCount();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The peak live thread count.")
+    public int getMaximumThreadCount();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("The total number of threads started.")
+    public long getTotalStartedThreadCount();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Current number of live daemon threads.")
+    public int getCurrentDaemonThreadCount();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Last data version.")
+    public long getLastDataVersion();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Sent messages count.")
+    public int getSentMessagesCount();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Sent bytes count.")
+    public long getSentBytesCount();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Received messages count.")
+    public int getReceivedMessagesCount();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Received bytes count.")
+    public long getReceivedBytesCount();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Outbound messages queue size.")
+    public int getOutboundMessagesQueueSize();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Start time of the grid node in milliseconds.")
+    public long getNodeStartTime();
+
+    /** {@inheritDoc} */
+    @MXBeanDescription("Total number of nodes.")
+    public int getTotalNodes();
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/010d02b8/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterMetricsMXBean.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterMetricsMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterMetricsMXBean.java
index 21c05db..ecd517b 100644
--- a/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterMetricsMXBean.java
+++ b/modules/core/src/main/java/org/apache/ignite/mxbean/ClusterMetricsMXBean.java
@@ -17,241 +17,69 @@
 
 package org.apache.ignite.mxbean;
 
-import org.apache.ignite.cluster.ClusterMetrics;
+import java.util.Map;
 
 /**
- * MBean for local node metrics.
+ * Cluster metrics MBean.
  */
-@MXBeanDescription("MBean that provides access to all local node metrics.")
-public interface ClusterMetricsMXBean extends ClusterMetrics {
-    /** {@inheritDoc} */
-    @MXBeanDescription("Last update time of this node metrics.")
-    public long getLastUpdateTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Maximum number of jobs that ever ran concurrently on this node.")
-    public int getMaximumActiveJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Number of currently active jobs concurrently executing on the node.")
-    public int getCurrentActiveJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Average number of active jobs concurrently executing on the node.")
-    public float getAverageActiveJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Maximum number of waiting jobs this node had.")
-    public int getMaximumWaitingJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Number of queued jobs currently waiting to be executed.")
-    public int getCurrentWaitingJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Average number of waiting jobs this node had queued.")
-    public float getAverageWaitingJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Maximum number of jobs rejected at once during a single collision resolution operation.")
-    public int getMaximumRejectedJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Number of jobs rejected after more recent collision resolution operation.")
-    public int getCurrentRejectedJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Average number of jobs this node rejects during collision resolution operations.")
-    public float getAverageRejectedJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription(
-        "Total number of jobs this node rejects during collision resolution operations since node startup.")
-    public int getTotalRejectedJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Maximum number of cancelled jobs this node ever had running concurrently.")
-    public int getMaximumCancelledJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Number of cancelled jobs that are still running.")
-    public int getCurrentCancelledJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Average number of cancelled jobs this node ever had running concurrently.")
-    public float getAverageCancelledJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Total number of cancelled jobs since node startup.")
-    public int getTotalCancelledJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Total number of jobs handled by the node.")
-    public int getTotalExecutedJobs();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Total time all finished jobs takes to execute on the node.")
-    public long getTotalJobsExecutionTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Maximum time a job ever spent waiting in a queue to be executed.")
-    public long getMaximumJobWaitTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Current wait time of oldest job.")
-    public long getCurrentJobWaitTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Average time jobs spend waiting in the queue to be executed.")
-    public double getAverageJobWaitTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Time it took to execute the longest job on the node.")
-    public long getMaximumJobExecuteTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Longest time a current job has been executing for.")
-    public long getCurrentJobExecuteTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Average time a job takes to execute on the node.")
-    public double getAverageJobExecuteTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Total number of tasks handled by the node.")
-    public int getTotalExecutedTasks();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Total time this node spent executing jobs.")
-    public long getTotalBusyTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Total time this node spent idling (not executing any jobs).")
-    public long getTotalIdleTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Time this node spend idling since executing last job.")
-    public long getCurrentIdleTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Percentage of time this node is busy executing jobs vs. idling.")
-    public float getBusyTimePercentage();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Percentage of time this node is idling vs. executing jobs.")
-    public float getIdleTimePercentage();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The number of CPUs available to the Java Virtual Machine.")
-    public int getTotalCpus();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The system load average; or a negative value if not available.")
-    public double getCurrentCpuLoad();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Average of CPU load values over all metrics kept in the history.")
-    public double getAverageCpuLoad();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Average time spent in CG since the last update.")
-    public double getCurrentGcCpuLoad();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The initial size of memory in bytes; -1 if undefined.")
-    public long getHeapMemoryInitialized();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Current heap size that is used for object allocation.")
-    public long getHeapMemoryUsed();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The amount of committed memory in bytes.")
-    public long getHeapMemoryCommitted();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The maximum amount of memory in bytes; -1 if undefined.")
-    public long getHeapMemoryMaximum();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The total amount of memory in bytes; -1 if undefined.")
-    public long getHeapMemoryTotal();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The initial size of memory in bytes; -1 if undefined.")
-    public long getNonHeapMemoryInitialized();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Current non-heap memory size that is used by Java VM.")
-    public long getNonHeapMemoryUsed();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Amount of non-heap memory in bytes that is committed for the JVM to use.")
-    public long getNonHeapMemoryCommitted();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Maximum amount of non-heap memory in bytes that can " +
-        "be used for memory management. -1 if undefined.")
-    public long getNonHeapMemoryMaximum();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Total amount of non-heap memory in bytes that can " +
-        "be used for memory management. -1 if undefined.")
-    public long getNonHeapMemoryTotal();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Uptime of the JVM in milliseconds.")
-    public long getUpTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Start time of the JVM in milliseconds.")
-    public long getStartTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Current number of live threads.")
-    public int getCurrentThreadCount();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The peak live thread count.")
-    public int getMaximumThreadCount();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("The total number of threads started.")
-    public long getTotalStartedThreadCount();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Current number of live daemon threads.")
-    public int getCurrentDaemonThreadCount();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Last data version.")
-    public long getLastDataVersion();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Sent messages count.")
-    public int getSentMessagesCount();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Sent bytes count.")
-    public long getSentBytesCount();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Received messages count.")
-    public int getReceivedMessagesCount();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Received bytes count.")
-    public long getReceivedBytesCount();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Outbound messages queue size.")
-    public int getOutboundMessagesQueueSize();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Start time of the grid node in milliseconds.")
-    public long getNodeStartTime();
-
-    /** {@inheritDoc} */
-    @MXBeanDescription("Total number of nodes.")
-    public int getTotalNodes();
+@MXBeanDescription("MBean that provides access to aggregated cluster metrics.")
+public interface ClusterMetricsMXBean extends ClusterLocalNodeMetricsMXBean {
+    /**
+     * Get count of server nodes.
+     *
+     * @return Count of server nodes.
+     */
+    @MXBeanDescription("Server nodes count.")
+    public int getTotalServerNodes();
+
+    /**
+     * Get count of client nodes.
+     *
+     * @return Count of client nodes.
+     */
+    @MXBeanDescription("Client nodes count.")
+    public int getTotalClientNodes();
+
+    /**
+     * Get current topology version.
+     *
+     * @return Current topology version.
+     */
+    @MXBeanDescription("Current topology version.")
+    public long getTopologyVersion();
+
+    /**
+     * Get the number of nodes that have specified attribute.
+     *
+     * @param attrName Attribute name.
+     * @param attrVal Attribute value.
+     * @param srv Include server nodes.
+     * @param client Include client nodes.
+     * @return The number of nodes that have specified attribute.
+     */
+    @MXBeanDescription("Get the number of nodes that have specified attribute.")
+    @MXBeanParametersNames(
+        {"attrName", "attrValue", "server", "client"}
+    )
+    @MXBeanParametersDescriptions(
+        {"Attribute name.", "Attribute value.", "Include server nodes.", "Include client nodes."}
+    )
+    public int countNodes(String attrName, String attrVal, boolean srv, boolean client);
+
+    /**
+     * Get the number of nodes grouped by the node attribute value.
+     *
+     * @param attrName Attribute name.
+     * @param srv Include server nodes.
+     * @param client Include client nodes.
+     * @return The number of nodes grouped by the node attribute value.
+     */
+    @MXBeanDescription("Get the number of nodes grouped by the node attribute.")
+    @MXBeanParametersNames(
+        {"attrName", "server", "client"}
+    )
+    @MXBeanParametersDescriptions(
+        {"Attribute name.", "Include server nodes.", "Include client nodes."}
+    )
+    public Map<Object, Integer> groupNodes(String attrName, boolean srv, boolean client);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/010d02b8/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java
index 2e4f248..790a397 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/ClusterNodeMetricsSelfTest.java
@@ -18,12 +18,18 @@
 package org.apache.ignite.internal;
 
 import java.io.Serializable;
+import java.util.Collections;
+import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
 import org.apache.ignite.GridTestTask;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.Ignition;
 import org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy;
 import org.apache.ignite.cluster.ClusterMetrics;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -32,6 +38,8 @@ import org.apache.ignite.events.Event;
 import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
 import org.apache.ignite.internal.processors.task.GridInternal;
 import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.messaging.MessagingListenActor;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
@@ -42,6 +50,9 @@ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.testframework.junits.common.GridCommonTest;
 
 import static org.apache.ignite.events.EventType.EVT_NODE_METRICS_UPDATED;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_BUILD_VER;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CLIENT_MODE;
+import static org.apache.ignite.internal.IgniteVersionUtils.VER_STR;
 
 /**
  * Grid node metrics self test.
@@ -362,6 +373,44 @@ public class ClusterNodeMetricsSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Test JMX metrics.
+     *
+     * @throws Exception If failed.
+     */
+    public void testJmxClusterMetrics() throws Exception {
+        Ignite node = grid();
+
+        Ignite node1 = startGrid(1);
+
+        Ignition.setClientMode(true);
+
+        Ignite node2 = startGrid(2);
+
+        waitForDiscovery(node2, node1, node);
+
+        JmxClusterMetricsHelper h = new JmxClusterMetricsHelper(node.configuration());
+
+        assertEquals(node.cluster().topologyVersion(), h.attr("TopologyVersion"));
+
+        assertEquals(2, h.attr("TotalServerNodes"));
+        assertEquals(1, h.attr("TotalClientNodes"));
+
+        assertEquals(3, h.countNodes(ATTR_BUILD_VER, VER_STR, true, true));
+        assertEquals(2, h.countNodes(ATTR_BUILD_VER, VER_STR, true, false));
+        assertEquals(1, h.countNodes(ATTR_BUILD_VER, VER_STR, false, true));
+        assertEquals(0, h.countNodes(ATTR_BUILD_VER, VER_STR, false, false));
+
+        assertEquals(2, h.countNodes(ATTR_CLIENT_MODE, "false", true, true));
+        assertEquals(0, h.countNodes(ATTR_CLIENT_MODE, "false", false, false));
+        assertEquals(1, h.countNodes(ATTR_CLIENT_MODE, "true", true, true));
+
+        assertEquals(F.asMap(false, 2, true, 1), h.groupNodes(ATTR_CLIENT_MODE, true, true));
+        assertEquals(F.asMap(false, 2), h.groupNodes(ATTR_CLIENT_MODE, true, false));
+        assertEquals(F.asMap(true, 1), h.groupNodes(ATTR_CLIENT_MODE, false, true));
+        assertEquals(Collections.emptyMap(), h.groupNodes(ATTR_CLIENT_MODE, false, false));
+    }
+
+    /**
      * Test message.
      */
     @SuppressWarnings("UnusedDeclaration")
@@ -377,4 +426,70 @@ public class ClusterNodeMetricsSelfTest extends GridCommonAbstractTest {
     private static class TestInternalTask extends GridTestTask {
         // No-op.
     }
+
+    /**
+     * Helper class to simplify ClusterMetricsMXBean testing.
+     */
+    private static class JmxClusterMetricsHelper {
+        /** MBean server. */
+        private final MBeanServer mbeanSrv;
+
+        /** ClusterMetrics MX bean name. */
+        private final ObjectName mbean;
+
+        /**
+         * @param cfg Ignite configuration.
+         * @throws MalformedObjectNameException Thrown in case of any errors.
+         */
+        private JmxClusterMetricsHelper(IgniteConfiguration cfg) throws MalformedObjectNameException {
+            this.mbeanSrv = cfg.getMBeanServer();
+
+            this.mbean = U.makeMBeanName(cfg.getIgniteInstanceName(), "Kernal",
+                ClusterMetricsMXBeanImpl.class.getSimpleName());
+        }
+
+        /**
+         * Invoke "countNodes" method through MBean server.
+         *
+         * @param attrName Node attribute name,
+         * @param attrVal Node attribute value,
+         * @param srv Include server nodes.
+         * @param client Include client nodes.
+         * @return Count of nodes filtered by node attribute.
+         * @throws Exception If failed.
+         */
+        private int countNodes(String attrName, String attrVal, boolean srv, boolean client) throws Exception {
+            String[] signature = {"java.lang.String", "java.lang.String", "boolean", "boolean"};
+            Object[] params = {attrName, attrVal, srv, client};
+
+            return (int)mbeanSrv.invoke(mbean, "countNodes", params, signature);
+        }
+
+        /**
+         * Invoke "groupNodes" method through MBean server.
+         *
+         * @param attrName Node attribute name.
+         * @param srv Include server nodes.
+         * @param client Include client nodes.
+         * @return The number of nodes grouped by node attribute name.
+         * @throws Exception If failed.
+         */
+        private Map groupNodes(String attrName, boolean srv, boolean client) throws Exception {
+            String[] signature = {"java.lang.String", "boolean", "boolean"};
+            Object[] params = {attrName, srv, client};
+
+            return (Map)mbeanSrv.invoke(mbean, "groupNodes", params, signature);
+        }
+
+        /**
+         * Get MBean attribute through MBean server.
+         *
+         * @param name Attribute name.
+         * @return Current value of attribute.
+         * @throws Exception If failed.
+         */
+        private Object attr(String name) throws Exception {
+            return mbeanSrv.getAttribute(mbean, name);
+        }
+    }
 }