Adding client and cluster JMX stats.

This commit is contained in:
Michael Nitschinger
2013-05-29 10:13:24 +02:00
parent 7f1dbfaa1d
commit a307d8f595
6 changed files with 213 additions and 26 deletions

View File

@@ -1,8 +1,13 @@
package com.couchbase.spring.monitor;
import com.couchbase.client.CouchbaseClient;
import org.springframework.web.client.RestTemplate;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
@@ -12,6 +17,8 @@ public abstract class AbstractMonitor {
private CouchbaseClient client;
private RestTemplate template = new RestTemplate();
protected AbstractMonitor(final CouchbaseClient client) {
this.client = client;
}
@@ -20,6 +27,16 @@ public abstract class AbstractMonitor {
return client;
}
protected RestTemplate getTemplate() {
return template;
}
protected String randomAvailableHostname() {
List<SocketAddress> available = (ArrayList) client.getAvailableServers();
Collections.shuffle(available);
return ((InetSocketAddress) available.get(0)).getHostName();
}
/**
* Fetches stats for all nodes.
*

View File

@@ -0,0 +1,64 @@
/**
* Copyright (C) 2009-2012 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
* IN THE SOFTWARE.
*/
package com.couchbase.spring.monitor;
import com.couchbase.client.CouchbaseClient;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
import java.net.SocketAddress;
/**
* Exposes basic client information.
*/
@ManagedResource(description = "Client Information")
public class ClientInfo extends AbstractMonitor {
public ClientInfo(final CouchbaseClient client) {
super(client);
}
@ManagedAttribute(description = "Hostnames of connected nodes")
public String getHostNames() {
StringBuilder result = new StringBuilder();
for (SocketAddress node : getStats().keySet()) {
result.append(node.toString()).append(",");
}
return result.toString();
}
@ManagedAttribute(description = "Number of connected nodes")
public int getNumberOfNodes() {
return getStats().keySet().size();
}
@ManagedAttribute(description = "Number of connected active nodes")
public int getNumberOfActiveNodes() {
return getClient().getAvailableServers().size();
}
@ManagedAttribute(description = "Number of connected inactive nodes")
public int getNumberOfInactiveNodes() {
return getClient().getUnavailableServers().size();
}
}

View File

@@ -1,13 +1,15 @@
package com.couchbase.spring.monitor;
import com.couchbase.client.CouchbaseClient;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedMetric;
import org.springframework.jmx.export.annotation.ManagedResource;
import java.net.SocketAddress;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.HashMap;
/**
* Exposes basic cluster information.
@@ -19,31 +21,54 @@ public class ClusterInfo extends AbstractMonitor {
super(client);
}
@ManagedAttribute(description = "All hostnames of nodes in the cluster")
public String getHostNames() {
StringBuilder result = new StringBuilder();
for (SocketAddress node : getStats().keySet()) {
result.append(node.toString()).append(",");
}
return result.toString();
@ManagedMetric(description = "Total RAM assigned")
public long getTotalRAMAssigned() {
return (Long) parseStorageTotals().get("ram").get("total");
}
@ManagedAttribute(description = "Number of nodes currently in the cluster")
public int getNumberOfNodes() {
return getStats().keySet().size();
@ManagedMetric(description = "Total RAM used")
public long getTotalRAMUsed() {
return (Long) parseStorageTotals().get("ram").get("used");
}
@ManagedAttribute(description = "Couchbase Server versions of nodes in the cluster")
public String getNodeVersions() {
StringBuilder result = new StringBuilder();
for(Map.Entry<SocketAddress,Map<String,String>> entry : getStats().entrySet()) {
for(Map.Entry<String, String> stat : entry.getValue().entrySet()) {
if (stat.getKey().equals("ep_version")) {
result.append(stat.getValue()).append(",");
}
}
}
return result.toString();
@ManagedMetric(description = "Total Disk Space assigned")
public long getTotalDiskAssigned() {
return (Long) parseStorageTotals().get("hdd").get("total");
}
@ManagedMetric(description = "Total Disk Space used")
public long getTotalDiskUsed() {
return (Long) parseStorageTotals().get("hdd").get("used");
}
@ManagedMetric(description = "Total Disk Space free")
public long getTotalDiskFree() {
return (Long) parseStorageTotals().get("hdd").get("free");
}
@ManagedAttribute(description = "Cluster is Balanced")
public boolean getIsBalanced() {
return (Boolean) fetchPoolInfo().get("balanced");
}
@ManagedAttribute(description = "Rebalance Status")
public String getRebalanceStatus() {
return (String) fetchPoolInfo().get("rebalanceStatus");
}
@ManagedAttribute(description = "Maximum Available Buckets")
public int getMaxBuckets() {
return (Integer) fetchPoolInfo().get("maxBucketCount");
}
private HashMap<String, Object> fetchPoolInfo() {
return getTemplate().getForObject("http://"
+ randomAvailableHostname() + ":8091/pools/default", HashMap.class);
}
private HashMap<String, HashMap> parseStorageTotals() {
HashMap<String, Object> stats = fetchPoolInfo();
return (HashMap<String, HashMap>) stats.get("storageTotals");
}
}