Skip to content

Commit 6dde355

Browse files
jmx-metrics-fix (#3713)
* properly handle missing metrics with non-wildcards * update changelog --------- Co-authored-by: jackshirazi <[email protected]>
1 parent cf3d0fc commit 6dde355

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Use subheadings with the "=====" level for adding notes for unreleased changes:
3636
* Restore compatibility with Java 7 - {pull}3657[#3657]
3737
* Avoid `ClassCastException` and issue warning when trying to use otel span links - {pull}3672[#3672]
3838
* Avoid `NullPointerException` with runtime attach API and invalid map entries - {pull}3712[#3712]
39+
* Enhance invalid state JMX metrics handling - {pull}3713[#3713]
3940
* Skips using NOFOLLOW_LINKS file open option when running on z/OS as it's unsupported there - {pull}3722[#3722]
4041
4142
[float]

apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import javax.management.ObjectInstance;
4747
import javax.management.ObjectName;
4848
import javax.management.RuntimeMBeanException;
49+
import javax.management.MBeanException;
50+
import javax.management.ReflectionException;
4951
import javax.management.openmbean.CompositeData;
5052
import javax.management.relation.MBeanServerNotificationFilter;
5153
import java.lang.management.ManagementFactory;
@@ -367,31 +369,39 @@ private void addJmxMetricRegistration(final JmxMetric jmxMetric, List<JmxMetricR
367369
MBeanInfo info = server.getMBeanInfo(objectName);
368370
MBeanAttributeInfo[] attrInfo = info.getAttributes();
369371
for (MBeanAttributeInfo attr : attrInfo) {
370-
try {
371-
final Object value = server.getAttribute(objectName, attr.getName());
372-
addJmxMetricRegistration(jmxMetric, registrations, objectName, value, attribute, attr.getName(), metricPrepend);
373-
} catch (AttributeNotFoundException e) {
374-
logger.warn("Can't create metric '{}' because attribute '{}' could not be found", jmxMetric, attribute.getJmxAttributeName());
375-
} catch (RuntimeMBeanException e) {
376-
if (e.getCause() instanceof UnsupportedOperationException) {
377-
//ignore this attribute
378-
} else {
379-
throw e;
380-
}
381-
}
372+
String attributeName = attr.getName();
373+
tryAddJmxMetric(jmxMetric, registrations, server, attribute, objectName, attributeName, metricPrepend);
382374
}
383375
} else {
384-
final Object value = server.getAttribute(objectName, attribute.getJmxAttributeName());
385-
try {
386-
addJmxMetricRegistration(jmxMetric, registrations, objectName, value, attribute, attribute.getJmxAttributeName(), null);
387-
} catch (AttributeNotFoundException e) {
388-
logger.warn("Can't create metric '{}' because attribute '{}' could not be found", jmxMetric, attribute.getJmxAttributeName());
389-
}
376+
String attributeName = attribute.getJmxAttributeName();
377+
tryAddJmxMetric(jmxMetric, registrations, server, attribute, objectName, attributeName, null);
390378
}
391379
}
392380
}
393381
}
394382

383+
private void tryAddJmxMetric(JmxMetric jmxMetric,
384+
List<JmxMetricRegistration> registrations,
385+
MBeanServer server,
386+
JmxMetric.Attribute attribute,
387+
ObjectName objectName,
388+
String attributeName,
389+
@Nullable String metricPrepend) throws MBeanException, InstanceNotFoundException, ReflectionException {
390+
391+
try {
392+
Object value = server.getAttribute(objectName, attributeName);
393+
addJmxMetricRegistration(jmxMetric, registrations, objectName, value, attribute, attributeName, metricPrepend);
394+
} catch (AttributeNotFoundException e) {
395+
logger.warn("Can't create metric '{}' because attribute '{}' could not be found", jmxMetric, attributeName);
396+
} catch (RuntimeMBeanException e) {
397+
if (e.getCause() instanceof UnsupportedOperationException) {
398+
// silently ignore this attribute, won't retry as it's not a transient runtime exception
399+
} else {
400+
throw e;
401+
}
402+
}
403+
}
404+
395405
private static boolean isWildcard(JmxMetric.Attribute attribute) {
396406
return "*".equals(attribute.getJmxAttributeName());
397407
}
@@ -486,7 +496,7 @@ public double get() {
486496
value = ((Number) ((CompositeData) server.getAttribute(objectName, jmxAttribute)).get(compositeDataKey)).doubleValue();
487497
}
488498
return value;
489-
} catch (InstanceNotFoundException | AttributeNotFoundException e) {
499+
} catch (InstanceNotFoundException | AttributeNotFoundException | RuntimeMBeanException e) {
490500
if (unsubscribeOnError) {
491501
unregister(tracer);
492502
}

0 commit comments

Comments
 (0)