Skip to content

Commit

Permalink
Handle missing attributes without failing (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
dehaansa authored Jun 1, 2021
1 parent 6edad7a commit 5f80eec
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class InstrumentHelper {
}
tupleToUpdates[tuple].add(prepareUpdateClosure(instrument, val, labels))
}
} else {
} else if (value != null) {
def labels = getLabels(mbean, labelFuncs)
def tuple = new Tuple(instrument, instrumentName, description, unit)
logger.fine("Recording ${instrumentName} - ${instrument.method} w/ ${value} - ${labels}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package io.opentelemetry.contrib.jmxmetrics
import groovy.transform.PackageScope
import javax.management.MBeanServerConnection
import javax.management.ObjectName
import javax.management.AttributeNotFoundException
import java.util.logging.Logger

/**
Expand Down Expand Up @@ -87,7 +88,12 @@ class MBeanHelper {

def ofInterest = isSingle ? [mbeans[0]]: mbeans
return ofInterest.collect {
it.getProperty(attribute)
try {
it.getProperty(attribute)
} catch (AttributeNotFoundException e) {
logger.warning("Expected attribute ${attribute} not found in mbean ${it.name()}")
null
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,39 @@ class InstrumentHelperTest extends Specification {
false | "multiple" | "Long" | "longValueObserver" | LONG_GAUGE | 234
}

@Unroll
def "handles nulls returned from MBeanHelper"() {
setup: "Create and register four Things and create ${quantity} MBeanHelper"
def thingName = "${quantity}:type=${instrumentMethod}.${attribute}.Thing"
def things = (0..3).collect { new Thing() }
things.eachWithIndex { thing, i ->
def name = "${thingName},thing=${i}"
mBeanServer.registerMBean(thing, new ObjectName(name))
}
def mbeanHelper = new MBeanHelper(jmxClient, "${thingName},*", isSingle)
mbeanHelper.fetch()

expect:
when:
def instrumentName = "${quantity}.${instrumentMethod}.counter"
def description = "${quantity} double counter description"
def instrument = otel.&"${instrumentMethod}"
def instrumentHelper = new InstrumentHelper(
mbeanHelper, instrumentName, description, "1",
["labelOne" : { "labelOneValue"}, "labelTwo": { mbean -> mbean.name().getKeyProperty("thing") }],
attribute, instrument)
instrumentHelper.update()

then:
def metrics = exportMetrics()
metrics.size() == 0

where:
isSingle | quantity | attribute | instrumentMethod | metricType | value
true | "single" | "Missing" | "longValueObserver" | LONG_GAUGE | null
false | "multiple" | "Missing" | "longValueObserver" | LONG_GAUGE | null
}

@Unroll
def "#instrumentMethod correctly classified"() {
expect:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,31 @@ class MBeanHelperTest extends Specification {
false | "multiple"
}
@Unroll
def "handles missing attributes"() {
setup:
def thingName = "io.opentelemetry.contrib.jmxmetrics:type=${quantity}MissingAttributeThing"
def things = (0..100).collect { new Thing(it as String) }
things.eachWithIndex { thing, i ->
def name = "${thingName},thing=${i}"
mBeanServer.registerMBean(thing, new ObjectName(name))
}
expect:
when: "We request a nonexistent attribute via MBeanHelper"
def mbeanHelper = new MBeanHelper(jmxClient, "${thingName},*", isSingle)
mbeanHelper.fetch()
then: "nulls are returned"
def returned = mbeanHelper.getAttribute("MissingAttribute")
returned == isSingle ? [null]: (0..100).collect {null}
where:
isSingle | quantity
true | "single"
false | "multiple"
}
interface ThingMBean {
String getSomeAttribute()
Expand Down

0 comments on commit 5f80eec

Please sign in to comment.