Skip to content

Commit 5f80eec

Browse files
authored
Handle missing attributes without failing (#39)
1 parent 6edad7a commit 5f80eec

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

contrib/jmx-metrics/src/main/groovy/io/opentelemetry/contrib/jmxmetrics/InstrumentHelper.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class InstrumentHelper {
106106
}
107107
tupleToUpdates[tuple].add(prepareUpdateClosure(instrument, val, labels))
108108
}
109-
} else {
109+
} else if (value != null) {
110110
def labels = getLabels(mbean, labelFuncs)
111111
def tuple = new Tuple(instrument, instrumentName, description, unit)
112112
logger.fine("Recording ${instrumentName} - ${instrument.method} w/ ${value} - ${labels}")

contrib/jmx-metrics/src/main/groovy/io/opentelemetry/contrib/jmxmetrics/MBeanHelper.groovy

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package io.opentelemetry.contrib.jmxmetrics
1919
import groovy.transform.PackageScope
2020
import javax.management.MBeanServerConnection
2121
import javax.management.ObjectName
22+
import javax.management.AttributeNotFoundException
2223
import java.util.logging.Logger
2324

2425
/**
@@ -87,7 +88,12 @@ class MBeanHelper {
8788

8889
def ofInterest = isSingle ? [mbeans[0]]: mbeans
8990
return ofInterest.collect {
90-
it.getProperty(attribute)
91+
try {
92+
it.getProperty(attribute)
93+
} catch (AttributeNotFoundException e) {
94+
logger.warning("Expected attribute ${attribute} not found in mbean ${it.name()}")
95+
null
96+
}
9197
}
9298
}
9399
}

contrib/jmx-metrics/src/test/groovy/io/opentelemetry/contrib/jmxmetrics/InstrumentHelperTest.groovy

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,39 @@ class InstrumentHelperTest extends Specification {
189189
false | "multiple" | "Long" | "longValueObserver" | LONG_GAUGE | 234
190190
}
191191

192+
@Unroll
193+
def "handles nulls returned from MBeanHelper"() {
194+
setup: "Create and register four Things and create ${quantity} MBeanHelper"
195+
def thingName = "${quantity}:type=${instrumentMethod}.${attribute}.Thing"
196+
def things = (0..3).collect { new Thing() }
197+
things.eachWithIndex { thing, i ->
198+
def name = "${thingName},thing=${i}"
199+
mBeanServer.registerMBean(thing, new ObjectName(name))
200+
}
201+
def mbeanHelper = new MBeanHelper(jmxClient, "${thingName},*", isSingle)
202+
mbeanHelper.fetch()
203+
204+
expect:
205+
when:
206+
def instrumentName = "${quantity}.${instrumentMethod}.counter"
207+
def description = "${quantity} double counter description"
208+
def instrument = otel.&"${instrumentMethod}"
209+
def instrumentHelper = new InstrumentHelper(
210+
mbeanHelper, instrumentName, description, "1",
211+
["labelOne" : { "labelOneValue"}, "labelTwo": { mbean -> mbean.name().getKeyProperty("thing") }],
212+
attribute, instrument)
213+
instrumentHelper.update()
214+
215+
then:
216+
def metrics = exportMetrics()
217+
metrics.size() == 0
218+
219+
where:
220+
isSingle | quantity | attribute | instrumentMethod | metricType | value
221+
true | "single" | "Missing" | "longValueObserver" | LONG_GAUGE | null
222+
false | "multiple" | "Missing" | "longValueObserver" | LONG_GAUGE | null
223+
}
224+
192225
@Unroll
193226
def "#instrumentMethod correctly classified"() {
194227
expect:

contrib/jmx-metrics/src/test/groovy/io/opentelemetry/contrib/jmxmetrics/MBeanHelperTest.groovy

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,31 @@ class MBeanHelperTest extends Specification {
8585
false | "multiple"
8686
}
8787
88+
@Unroll
89+
def "handles missing attributes"() {
90+
setup:
91+
def thingName = "io.opentelemetry.contrib.jmxmetrics:type=${quantity}MissingAttributeThing"
92+
def things = (0..100).collect { new Thing(it as String) }
93+
things.eachWithIndex { thing, i ->
94+
def name = "${thingName},thing=${i}"
95+
mBeanServer.registerMBean(thing, new ObjectName(name))
96+
}
97+
98+
expect:
99+
when: "We request a nonexistent attribute via MBeanHelper"
100+
def mbeanHelper = new MBeanHelper(jmxClient, "${thingName},*", isSingle)
101+
mbeanHelper.fetch()
102+
103+
then: "nulls are returned"
104+
def returned = mbeanHelper.getAttribute("MissingAttribute")
105+
returned == isSingle ? [null]: (0..100).collect {null}
106+
107+
where:
108+
isSingle | quantity
109+
true | "single"
110+
false | "multiple"
111+
}
112+
88113
interface ThingMBean {
89114
90115
String getSomeAttribute()

0 commit comments

Comments
 (0)