Author: jbellis Date: Tue Aug 30 13:19:59 2011 New Revision: 1163201 URL: http://svn.apache.org/viewvc?rev=1163201&view=rev Log: Expose gossip/FD info to JMX patch by Patricio Echague; reviewed by brandonwilliams for CASSANDRA-2806
Modified: cassandra/trunk/CHANGES.txt cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetector.java cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetectorMBean.java cassandra/trunk/src/java/org/apache/cassandra/gms/Gossiper.java cassandra/trunk/src/java/org/apache/cassandra/tools/NodeCmd.java cassandra/trunk/src/java/org/apache/cassandra/tools/NodeProbe.java Modified: cassandra/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=1163201&r1=1163200&r2=1163201&view=diff ============================================================================== --- cassandra/trunk/CHANGES.txt (original) +++ cassandra/trunk/CHANGES.txt Tue Aug 30 13:19:59 2011 @@ -47,6 +47,7 @@ * LeveledCompactionStrategy (CASSANDRA-1608, 3085) * Improvements of the CLI `describe` command (CASSANDRA-2630) * reduce window where dropped CF sstables may not be deleted (CASSANDRA-2942) + * Expose gossip/FD info to JMX (CASSANDRA-2806) 0.8.5 Modified: cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetector.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetector.java?rev=1163201&r1=1163200&r2=1163201&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetector.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetector.java Tue Aug 30 13:19:59 2011 @@ -21,6 +21,7 @@ package org.apache.cassandra.gms; import java.io.*; import java.lang.management.ManagementFactory; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.*; import javax.management.MBeanServer; import javax.management.ObjectName; @@ -41,6 +42,7 @@ import org.apache.cassandra.utils.FBUtil */ public class FailureDetector implements IFailureDetector, FailureDetectorMBean { + public static final String MBEAN_NAME = "org.apache.cassandra.net:type=FailureDetector"; public static final IFailureDetector instance = new FailureDetector(); private static Logger logger_ = LoggerFactory.getLogger(FailureDetector.class); private static final int sampleSize_ = 1000; @@ -56,7 +58,7 @@ public class FailureDetector implements try { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); - mbs.registerMBean(this, new ObjectName("org.apache.cassandra.net:type=FailureDetector")); + mbs.registerMBean(this, new ObjectName(MBEAN_NAME)); } catch (Exception e) { @@ -70,12 +72,38 @@ public class FailureDetector implements for (Map.Entry<InetAddress, EndpointState> entry : Gossiper.instance.endpointStateMap.entrySet()) { sb.append(entry.getKey()).append("\n"); - for (Map.Entry<ApplicationState, VersionedValue> state : entry.getValue().applicationState.entrySet()) - sb.append(" ").append(state.getKey()).append(":").append(state.getValue().value).append("\n"); + appendEndpointState(sb, entry.getValue()); } return sb.toString(); } + public Map<String, String> getSimpleStates() + { + Map<String, String> nodesStatus = new HashMap<String, String>(Gossiper.instance.endpointStateMap.size()); + for (Map.Entry<InetAddress, EndpointState> entry : Gossiper.instance.endpointStateMap.entrySet()) + { + if (entry.getValue().isAlive()) + nodesStatus.put(entry.getKey().toString(), "UP"); + else + nodesStatus.put(entry.getKey().toString(), "DOWN"); + } + return nodesStatus; + } + + public String getEndpointState(String address) throws UnknownHostException + { + StringBuilder sb = new StringBuilder(); + EndpointState endpointState = Gossiper.instance.getEndpointStateForEndpoint(InetAddress.getByName(address)); + appendEndpointState(sb, endpointState); + return sb.toString(); + } + + private void appendEndpointState(StringBuilder sb, EndpointState endpointState) + { + for (Map.Entry<ApplicationState, VersionedValue> state : endpointState.applicationState.entrySet()) + sb.append(" ").append(state.getKey()).append(":").append(state.getValue().value).append("\n"); + } + /** * Dump the inter arrival times for examination if necessary. */ Modified: cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetectorMBean.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetectorMBean.java?rev=1163201&r1=1163200&r2=1163201&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetectorMBean.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/gms/FailureDetectorMBean.java Tue Aug 30 13:19:59 2011 @@ -18,6 +18,9 @@ package org.apache.cassandra.gms; +import java.net.UnknownHostException; +import java.util.Map; + public interface FailureDetectorMBean { public void dumpInterArrivalTimes(); @@ -25,6 +28,10 @@ public interface FailureDetectorMBean public void setPhiConvictThreshold(int phi); public int getPhiConvictThreshold(); - + public String getAllEndpointStates(); + + public String getEndpointState(String address) throws UnknownHostException; + + public Map<String, String> getSimpleStates(); } Modified: cassandra/trunk/src/java/org/apache/cassandra/gms/Gossiper.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/gms/Gossiper.java?rev=1163201&r1=1163200&r2=1163201&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/gms/Gossiper.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/gms/Gossiper.java Tue Aug 30 13:19:59 2011 @@ -21,11 +21,16 @@ package org.apache.cassandra.gms; import java.io.DataOutputStream; import java.io.IOError; import java.io.IOException; +import java.lang.management.ManagementFactory; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.*; import java.util.Map.Entry; import java.util.concurrent.*; +import javax.management.MBeanServer; +import javax.management.ObjectName; + import org.apache.cassandra.dht.Token; import org.apache.cassandra.db.SystemTable; import org.apache.cassandra.io.util.FastByteArrayOutputStream; @@ -54,8 +59,10 @@ import org.apache.cassandra.service.Stor * of the three above mentioned messages updates the Failure Detector with the liveness information. */ -public class Gossiper implements IFailureDetectionEventListener +public class Gossiper implements IFailureDetectionEventListener, GossiperMBean { + private static final String MBEAN_NAME = "org.apache.cassandra.net:type=Gossiper"; + private static final DebuggableScheduledThreadPoolExecutor executor = new DebuggableScheduledThreadPoolExecutor("GossipTasks"); static final ApplicationState[] STATES = ApplicationState.values(); @@ -172,6 +179,17 @@ public class Gossiper implements IFailur FatClientTimeout = (long)(QUARANTINE_DELAY / 2); /* register with the Failure Detector for receiving Failure detector events */ FailureDetector.instance.registerFailureDetectionEventListener(this); + + // Register this instance with JMX + try + { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + mbs.registerMBean(this, new ObjectName(MBEAN_NAME)); + } + catch (Exception e) + { + throw new RuntimeException(e); + } } /** @@ -1010,4 +1028,20 @@ public class Gossiper implements IFailur endpointStateMap.put(addr, localState); } } + + public int getVersion(String address) throws UnknownHostException + { + return getVersion(InetAddress.getByName(address)); + } + + public long getEndpointDowntime(String address) throws UnknownHostException + { + return getEndpointDowntime(InetAddress.getByName(address)); + } + + public int getCurrentGenerationNumber(String address) throws UnknownHostException + { + return getCurrentGenerationNumber(InetAddress.getByName(address)); + } + } Modified: cassandra/trunk/src/java/org/apache/cassandra/tools/NodeCmd.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/tools/NodeCmd.java?rev=1163201&r1=1163200&r2=1163201&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/tools/NodeCmd.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/tools/NodeCmd.java Tue Aug 30 13:19:59 2011 @@ -80,7 +80,7 @@ public class NodeCmd SETCACHECAPACITY, GETCOMPACTIONTHRESHOLD, SETCOMPACTIONTHRESHOLD, NETSTATS, CFHISTOGRAMS, COMPACTIONSTATS, DISABLEGOSSIP, ENABLEGOSSIP, INVALIDATEKEYCACHE, INVALIDATEROWCACHE, DISABLETHRIFT, ENABLETHRIFT, STATUSTHRIFT, JOIN, SETCOMPACTIONTHROUGHPUT, GETENDPOINTS, - REFRESH + REFRESH, GOSSIPINFO } @@ -107,6 +107,7 @@ public class NodeCmd addCmdHelp(header, "disablethrift", "Disable thrift server"); addCmdHelp(header, "enablethrift", "Reenable thrift server"); addCmdHelp(header, "statusthrift", "Status of thrift server"); + addCmdHelp(header, "gossipinfo", "Shows the gossip information for the cluster"); // One arg addCmdHelp(header, "netstats [host]", "Print network information on provided host (connecting node by default)"); @@ -706,6 +707,8 @@ public class NodeCmd probe.loadNewSSTables(arguments[0], arguments[1]); break; + case GOSSIPINFO : nodeCmd.printGossipInfo(System.out); break; + default : throw new RuntimeException("Unreachable code."); @@ -714,6 +717,10 @@ public class NodeCmd System.exit(0); } + private void printGossipInfo(PrintStream out) { + out.println(probe.getGossipInfo()); + } + private static void badUse(String useStr) { System.err.println(useStr); Modified: cassandra/trunk/src/java/org/apache/cassandra/tools/NodeProbe.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/tools/NodeProbe.java?rev=1163201&r1=1163200&r2=1163201&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/tools/NodeProbe.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/tools/NodeProbe.java Tue Aug 30 13:19:59 2011 @@ -47,6 +47,8 @@ import org.apache.cassandra.db.ColumnFam import org.apache.cassandra.db.compaction.CompactionManager; import org.apache.cassandra.db.compaction.CompactionManagerMBean; import org.apache.cassandra.dht.Token; +import org.apache.cassandra.gms.FailureDetector; +import org.apache.cassandra.gms.FailureDetectorMBean; import org.apache.cassandra.locator.EndpointSnitchInfoMBean; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.net.MessagingServiceMBean; @@ -76,6 +78,7 @@ public class NodeProbe private RuntimeMXBean runtimeProxy; private StreamingServiceMBean streamProxy; public MessagingServiceMBean msProxy; + private FailureDetectorMBean fdProxy; /** * Creates a NodeProbe using the specified JMX host, port, username, and password. @@ -150,6 +153,8 @@ public class NodeProbe streamProxy = JMX.newMBeanProxy(mbeanServerConn, name, StreamingServiceMBean.class); name = new ObjectName(CompactionManager.MBEAN_OBJECT_NAME); compactionProxy = JMX.newMBeanProxy(mbeanServerConn, name, CompactionManagerMBean.class); + name = new ObjectName(FailureDetector.MBEAN_NAME); + fdProxy = JMX.newMBeanProxy(mbeanServerConn, name, FailureDetectorMBean.class); } catch (MalformedObjectNameException e) { throw new RuntimeException( @@ -596,6 +601,11 @@ public class NodeProbe { ssProxy.loadNewSSTables(ksName, cfName); } + + public String getGossipInfo() + { + return fdProxy.getAllEndpointStates(); + } } class ColumnFamilyStoreMBeanIterator implements Iterator<Map.Entry<String, ColumnFamilyStoreMBean>>