Skip to content

Commit 87b939c

Browse files
committed
Add exception handling for MBean disappearing between listing and evaluation
Closes instaclustr#27. Squashed commit of the following: commit c8eafefc7732d84114c990f81d6ad70489dafcec Author: Adam Zegelin <adam@zegelin.com> Date: Fri Feb 21 15:20:55 2020 -0800 Code cleanup. commit 425df4699f963213c5498b3f1eedec5fdb38a609 Merge: 0b5e2c0 21307ab Author: Adam Zegelin <adam@zegelin.com> Date: Fri Feb 21 15:11:05 2020 -0800 Merge branch 'fix-mbean-jmx-harvester' of https://github.com/suhailpatel/cassandra-exporter into suhailpatel-fix-mbean-jmx-harvester commit 21307ab Author: Suhail Patel <me@suhailpatel.com> Date: Tue Jul 9 16:46:24 2019 +0100 Dynamically update the set of current MBeans as we go along Again, if exceptions occur in other parts of the pipeline, MBeans are registered but are not removed which causes other bugs. Note that we use an immutable copy of the sets because the currentMBeans set is being updated constantly. commit c4b46dc Author: Suhail Patel <me@suhailpatel.com> Date: Sat Jul 6 20:51:06 2019 +0100 Add exception handling for MBean disappearing between listing and evaluation There was a condition where evaluating the set of added MBean can cause an exception. This would occur if the MBean had disappeared between listing the MBean and extracting the MBean info. If this happened in the middle of a set of added MBeans, it would mean our current MBeans set in the JMXHarvester isn't up to date with the current MBeans. This has cascading impact down the line because there are MBeans registered from previous runs that are not correctly associated with the set of current MBeans. This means they will never be cleaned up. This has impact on the collect stage which then results in other exceptions. We found this occur during Repair jobs when the repair durations are very small.
1 parent 0b5e2c0 commit 87b939c

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

standalone/src/main/java/com/zegelin/cassandra/exporter/JMXHarvester.java

+19-8
Original file line numberDiff line numberDiff line change
@@ -33,31 +33,43 @@ public class JMXHarvester extends Harvester {
3333
addCollectorFactory(RemoteGossiperMBeanMetricFamilyCollector.factory(metadataFactory));
3434
}
3535

36-
private Set<ObjectInstance> currentMBeans = ImmutableSet.of();
36+
private Set<ObjectInstance> currentMBeans = Sets.newHashSet();
3737

3838
void reconcileMBeans() {
3939
try {
40-
final Set<ObjectInstance> mBeans = mBeanServerConnection.queryMBeans(null, null);
40+
final Set<ObjectInstance> newMBeans = mBeanServerConnection.queryMBeans(null, null);
4141

4242
// unregister
4343
{
44-
final Set<ObjectInstance> removedMBeans = Sets.difference(currentMBeans, mBeans);
44+
final Set<ObjectInstance> removedMBeans = Sets.difference(currentMBeans, newMBeans);
4545

4646
logger.debug("Removing {} old MBeans.", removedMBeans.size());
4747

4848
for (final ObjectInstance instance : removedMBeans) {
4949
unregisterMBean(instance.getObjectName());
50+
currentMBeans.remove(instance);
5051
}
5152
}
5253

5354
// register
5455
{
55-
final Set<ObjectInstance> addedMBeans = Sets.difference(mBeans, currentMBeans);
56+
final Set<ObjectInstance> addedMBeans = Sets.difference(newMBeans, currentMBeans);
5657

5758
logger.debug("Found {} new MBeans.", addedMBeans.size());
5859

5960
for (final ObjectInstance instance : addedMBeans) {
60-
final MBeanInfo mBeanInfo = mBeanServerConnection.getMBeanInfo(instance.getObjectName());
61+
final MBeanInfo mBeanInfo;
62+
try {
63+
mBeanInfo = mBeanServerConnection.getMBeanInfo(instance.getObjectName());
64+
65+
} catch (final InstanceNotFoundException e) {
66+
// We may get an InstanceNotFoundException if the mBean was
67+
// really short lived (such as for a repair job or similar)
68+
// and Cassandra unregistered it between the probe and this
69+
// instance being evaluated
70+
continue;
71+
}
72+
6173
final Descriptor mBeanDescriptor = mBeanInfo.getDescriptor();
6274

6375
final String interfaceClassName = (String) mBeanDescriptor.getFieldValue(JMX.INTERFACE_CLASS_NAME_FIELD);
@@ -79,7 +91,7 @@ void reconcileMBeans() {
7991

8092
logger.debug("Registering MBean/MXBean {}.", instance);
8193

82-
final boolean isMXBean = Boolean.valueOf((String) mBeanDescriptor.getFieldValue(JMX.MXBEAN_FIELD));
94+
final boolean isMXBean = Boolean.parseBoolean((String) mBeanDescriptor.getFieldValue(JMX.MXBEAN_FIELD));
8395

8496
final ObjectName objectName = instance.getObjectName();
8597
final Object mBeanProxy;
@@ -90,11 +102,10 @@ void reconcileMBeans() {
90102
}
91103

92104
registerMBean(mBeanProxy, objectName);
105+
currentMBeans.add(instance);
93106
}
94107
}
95108

96-
currentMBeans = mBeans;
97-
98109
} catch (final Throwable e) {
99110
logger.error("Failed to reconcile MBeans.", e);
100111
}

0 commit comments

Comments
 (0)