diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index a127095c53..4c9fed2f6f 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -36,6 +36,7 @@ Use subheadings with the "=====" level for adding notes for unreleased changes: * Restore compatibility with Java 7 - {pull}3657[#3657] * Avoid `ClassCastException` and issue warning when trying to use otel span links - {pull}3672[#3672] * Avoid `NullPointerException` with runtime attach API and invalid map entries - {pull}3712[#3712] +* Enhance invalid state JMX metrics handling - {pull}3713[#3713] * Skips using NOFOLLOW_LINKS file open option when running on z/OS as it's unsupported there - {pull}3722[#3722] [float] diff --git a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java index 5c3733a639..6518f4f03e 100644 --- a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java +++ b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java @@ -46,6 +46,8 @@ import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.RuntimeMBeanException; +import javax.management.MBeanException; +import javax.management.ReflectionException; import javax.management.openmbean.CompositeData; import javax.management.relation.MBeanServerNotificationFilter; import java.lang.management.ManagementFactory; @@ -367,31 +369,39 @@ private void addJmxMetricRegistration(final JmxMetric jmxMetric, List registrations, + MBeanServer server, + JmxMetric.Attribute attribute, + ObjectName objectName, + String attributeName, + @Nullable String metricPrepend) throws MBeanException, InstanceNotFoundException, ReflectionException { + + try { + Object value = server.getAttribute(objectName, attributeName); + addJmxMetricRegistration(jmxMetric, registrations, objectName, value, attribute, attributeName, metricPrepend); + } catch (AttributeNotFoundException e) { + logger.warn("Can't create metric '{}' because attribute '{}' could not be found", jmxMetric, attributeName); + } catch (RuntimeMBeanException e) { + if (e.getCause() instanceof UnsupportedOperationException) { + // silently ignore this attribute, won't retry as it's not a transient runtime exception + } else { + throw e; + } + } + } + private static boolean isWildcard(JmxMetric.Attribute attribute) { return "*".equals(attribute.getJmxAttributeName()); } @@ -486,7 +496,7 @@ public double get() { value = ((Number) ((CompositeData) server.getAttribute(objectName, jmxAttribute)).get(compositeDataKey)).doubleValue(); } return value; - } catch (InstanceNotFoundException | AttributeNotFoundException e) { + } catch (InstanceNotFoundException | AttributeNotFoundException | RuntimeMBeanException e) { if (unsubscribeOnError) { unregister(tracer); }