Migrate JMX metrics last test to Java (#106)

* Migrate JMX metrics last test to Java

* DisplayName
This commit is contained in:
Anuraag Agrawal 2021-10-04 22:56:24 +09:00 committed by GitHub
parent d132dc4cfb
commit 2edfb184a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 562 additions and 238 deletions

View File

@ -1,238 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.jmxmetrics
import static io.opentelemetry.api.common.AttributeKey.stringKey
import static io.opentelemetry.sdk.metrics.data.MetricDataType.DOUBLE_GAUGE
import static io.opentelemetry.sdk.metrics.data.MetricDataType.DOUBLE_SUM
import static io.opentelemetry.sdk.metrics.data.MetricDataType.HISTOGRAM
import static io.opentelemetry.sdk.metrics.data.MetricDataType.LONG_GAUGE
import static io.opentelemetry.sdk.metrics.data.MetricDataType.LONG_SUM
import static java.lang.management.ManagementFactory.getPlatformMBeanServer
import io.opentelemetry.api.common.Attributes
import io.opentelemetry.api.metrics.GlobalMeterProvider
import javax.management.MBeanServer
import javax.management.ObjectName
import javax.management.remote.JMXConnectorServer
import javax.management.remote.JMXConnectorServerFactory
import javax.management.remote.JMXServiceURL
import org.junit.Rule
import org.junit.rules.TestName
import org.junit.rules.TestRule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll
class InstrumentHelperTest extends Specification {
@Rule
public final TestRule name = new TestName()
@Shared
MBeanServer mBeanServer
@Shared
JMXConnectorServer jmxServer
@Shared
JmxClient jmxClient
@Shared
OtelHelper otel
def setup() {
mBeanServer = getPlatformMBeanServer()
def serviceUrl = new JMXServiceURL('rmi', 'localhost', 0)
jmxServer = JMXConnectorServerFactory.newJMXConnectorServer(serviceUrl, [:], mBeanServer)
jmxServer.start()
def completeAddress = jmxServer.getAddress()
def jmxConfig = new JmxConfig(new Properties().tap {
it.setProperty(JmxConfig.METRICS_EXPORTER_TYPE, 'inmemory')
it.setProperty(JmxConfig.SERVICE_URL, "${completeAddress}")
})
jmxClient = new JmxClient(jmxConfig)
// Set up a MeterSdk per test to be able to collect its metrics alone
def gme = new GroovyMetricEnvironment(jmxConfig, name.methodName, '')
otel = new OtelHelper(jmxClient, gme)
}
def cleanup() {
jmxServer.stop()
}
interface ThingMBean {
double getDouble()
long getLong()
}
static class Thing implements ThingMBean {
@Override
double getDouble() {
return 123.456
}
@Override
long getLong() {
return 234
}
}
def exportMetrics() {
def provider = GlobalMeterProvider.get().get(name.methodName, '', null)
return provider.collectAll(0).sort { md1, md2 ->
def p1 = md1.data.points[0]
def p2 = md2.data.points[0]
def s1 = p1.startEpochNanos
def s2 = p2.startEpochNanos
if (s1 == s2) {
if (md1.type == HISTOGRAM) {
return p1.counts[0] <=> p2.counts[0]
}
return p1.value <=> p2.value
}
s1 <=> s2
}
}
@Unroll
def "#instrumentMethod via #quantity MBeanHelper"() {
setup:
"Create and register four Things and create ${quantity} MBeanHelper"
def thingName = "${quantity}:type=${instrumentMethod}.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() == 1
metrics.each { metric ->
assert metric.name == instrumentName
assert metric.description == description
assert metric.unit == "1"
assert metric.type == metricType
assert metric.data.points.size() == isSingle ? 1 : 4
metric.data.points.sort { a, b -> String.compare(a.attributes.get(stringKey("labelTwo")), b.attributes.get(stringKey("labelTwo"))) }
metric.data.points.eachWithIndex { point, i ->
assert point.attributes == Attributes.of(stringKey("labelOne"), "labelOneValue", stringKey("labelTwo"), "${i}".toString())
if (metricType == HISTOGRAM) {
assert point.count == 1
assert point.sum == value
assert point.counts[6].value == 1
} else {
assert point.value == value
}
}
}
where:
isSingle | quantity | attribute | instrumentMethod | metricType | value
true | "single" | "Double" | "doubleCounter" | DOUBLE_SUM | 123.456
false | "multiple" | "Double" | "doubleCounter" | DOUBLE_SUM | 123.456
true | "single" | "Double" | "doubleUpDownCounter" | DOUBLE_SUM | 123.456
false | "multiple" | "Double" | "doubleUpDownCounter" | DOUBLE_SUM | 123.456
true | "single" | "Long" | "longCounter" | LONG_SUM | 234
false | "multiple" | "Long" | "longCounter" | LONG_SUM | 234
true | "single" | "Long" | "longUpDownCounter" | LONG_SUM | 234
false | "multiple" | "Long" | "longUpDownCounter" | LONG_SUM | 234
true | "single" | "Double" | "doubleHistogram" | HISTOGRAM | 123.456
false | "multiple" | "Double" | "doubleHistogram" | HISTOGRAM | 123.456
true | "single" | "Long" | "longHistogram" | HISTOGRAM | 234
false | "multiple" | "Long" | "longHistogram" | HISTOGRAM | 234
true | "single" | "Double" | "doubleCounterCallback" | DOUBLE_SUM | 123.456
false | "multiple" | "Double" | "doubleCounterCallback" | DOUBLE_SUM | 123.456
true | "single" | "Double" | "doubleUpDownCounterCallback" | DOUBLE_SUM | 123.456
false | "multiple" | "Double" | "doubleUpDownCounterCallback" | DOUBLE_SUM | 123.456
true | "single" | "Long" | "longCounterCallback" | LONG_SUM | 234
false | "multiple" | "Long" | "longCounterCallback" | LONG_SUM | 234
true | "single" | "Long" | "longUpDownCounterCallback" | LONG_SUM | 234
false | "multiple" | "Long" | "longUpDownCounterCallback" | LONG_SUM | 234
true | "single" | "Double" | "doubleValueCallback" | DOUBLE_GAUGE | 123.456
false | "multiple" | "Double" | "doubleValueCallback" | DOUBLE_GAUGE | 123.456
true | "single" | "Long" | "longValueCallback" | LONG_GAUGE | 234
false | "multiple" | "Long" | "longValueCallback" | 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" | "longValueCallback" | LONG_GAUGE | null
false | "multiple" | "Missing" | "longValueCallback" | LONG_GAUGE | null
}
@Unroll
def "#instrumentMethod correctly classified"() {
expect:
def instrument = otel.&"${instrumentMethod}"
assert InstrumentHelper.instrumentIsObserver(instrument) == isObserver
assert InstrumentHelper.instrumentIsCounter(instrument) == isCounter
where:
instrumentMethod | isObserver | isCounter
"doubleCounter" | false | true
"longCounter" | false | true
"doubleCounterCallback" | true | false
"longCounterCallback" | true | false
"doubleUpDownCounter" | false | true
"longUpDownCounter" | false | true
"doubleUpDownCounterCallback" | true | false
"longUpDownCounterCallback" | true | false
"doubleValueCallback" | true | false
"longValueCallback" | true | false
"doubleHistogram" | false | false
"longHistogram" | false | false
}
}

View File

@ -0,0 +1,562 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.jmxmetrics;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
import groovy.lang.Closure;
import groovy.util.Eval;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.data.DoublePointData;
import io.opentelemetry.sdk.metrics.data.LongPointData;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Stream;
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
class InstrumenterHelperTest {
private static final MBeanServer mbeanServer = getPlatformMBeanServer();
private static final Set<ObjectInstance> registeredBeans = new HashSet<>();
private static JMXConnectorServer jmxServer;
private static JmxClient jmxClient;
// Will eventually be replaced with Jupiter extension in sdk-testing
private SdkMeterProvider meterProvider;
private OtelHelper otel;
@BeforeAll
static void setUp() throws Exception {
JMXServiceURL serviceUrl = new JMXServiceURL("rmi", "localhost", 0);
jmxServer =
JMXConnectorServerFactory.newJMXConnectorServer(
serviceUrl, Collections.emptyMap(), mbeanServer);
jmxServer.start();
JMXServiceURL completeAddress = jmxServer.getAddress();
Properties props = new Properties();
props.setProperty(JmxConfig.SERVICE_URL, completeAddress.toString());
jmxClient = new JmxClient(new JmxConfig(props));
}
@AfterAll
static void tearDown() throws Exception {
jmxServer.stop();
}
@BeforeEach
void setupOtel() {
meterProvider = SdkMeterProvider.builder().build();
otel = new OtelHelper(jmxClient, new GroovyMetricEnvironment(meterProvider, "otel.test"));
}
@AfterEach
void unregisterBeans() throws Exception {
for (ObjectInstance bean : registeredBeans) {
mbeanServer.unregisterMBean(bean.getObjectName());
}
registeredBeans.clear();
}
@Nested
@DisplayName("InstrumenterHelperTest - Single Metric")
class Single {
@ParameterizedTest
@ValueSource(
strings = {
"doubleCounter",
"doubleUpDownCounter",
"doubleCounterCallback",
"doubleUpDownCounterCallback"
})
void doubleSum(String instrumentMethod) throws Exception {
String thingName = "single:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "single." + instrumentMethod + ".counter";
String description = "single double counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Double");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasDoubleSum()
.points()
.satisfiesExactly(this::assertDoublePoint));
}
@ParameterizedTest
@ValueSource(
strings = {
"longCounter",
"longUpDownCounter",
"longCounterCallback",
"longUpDownCounterCallback"
})
void longSum(String instrumentMethod) throws Exception {
String thingName = "single:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "single." + instrumentMethod + ".counter";
String description = "single long counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Long");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasLongSum()
.points()
.satisfiesExactly(this::assertLongPoint));
}
@ParameterizedTest
@ValueSource(strings = {"doubleHistogram", "longHistogram"})
void histogram(String instrumentMethod) throws Exception {
String thingName = "single:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "single." + instrumentMethod + ".counter";
String description = "single long counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Long");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasDoubleHistogram()
.points()
.satisfiesExactly(
point ->
assertThat(point)
.hasSum(234)
.hasCount(1)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "0"))));
}
@Test
void doubleValueCallback() throws Exception {
String instrumentMethod = "doubleValueCallback";
String thingName = "single:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "single." + instrumentMethod + ".counter";
String description = "single double counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Double");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasDoubleGauge()
.points()
.satisfiesExactly(this::assertDoublePoint));
}
@Test
void longValueCallback() throws Exception {
String instrumentMethod = "longValueCallback";
String thingName = "single:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "single." + instrumentMethod + ".counter";
String description = "single double counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Long");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasLongGauge()
.points()
.satisfiesExactly(this::assertLongPoint));
}
private void assertDoublePoint(DoublePointData point) {
assertThat(point)
.hasValue(123.456)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"), attributeEntry("labelTwo", "0"));
}
private void assertLongPoint(LongPointData point) {
assertThat(point)
.hasValue(234)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"), attributeEntry("labelTwo", "0"));
}
}
@Nested
@DisplayName("InstrumenterHelperTest - Multiple Metrics")
class Multiple {
@ParameterizedTest
@ValueSource(
strings = {
"doubleCounter",
"doubleUpDownCounter",
"doubleCounterCallback",
"doubleUpDownCounterCallback"
})
void doubleSum(String instrumentMethod) throws Exception {
String thingName = "multiple:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "multiple." + instrumentMethod + ".counter";
String description = "multiple double counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Double");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasDoubleSum()
.points()
.satisfiesExactlyInAnyOrder(assertDoublePoints()));
}
@ParameterizedTest
@ValueSource(
strings = {
"longCounter",
"longUpDownCounter",
"longCounterCallback",
"longUpDownCounterCallback"
})
void longSum(String instrumentMethod) throws Exception {
String thingName = "multiple:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "multiple." + instrumentMethod + ".counter";
String description = "multiple long counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Long");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasLongSum()
.points()
.satisfiesExactlyInAnyOrder(assertLongPoints()));
}
@ParameterizedTest
@ValueSource(strings = {"doubleHistogram", "longHistogram"})
void histogram(String instrumentMethod) throws Exception {
String thingName = "multiple:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "multiple." + instrumentMethod + ".counter";
String description = "multiple long counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Long");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasDoubleHistogram()
.points()
.satisfiesExactlyInAnyOrder(
point ->
assertThat(point)
.hasSum(234)
.hasCount(1)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "0")),
point ->
assertThat(point)
.hasSum(234)
.hasCount(1)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "1")),
point ->
assertThat(point)
.hasSum(234)
.hasCount(1)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "2")),
point ->
assertThat(point)
.hasSum(234)
.hasCount(1)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "3"))));
}
@Test
void doubleValueCallback() throws Exception {
String instrumentMethod = "doubleValueCallback";
String thingName = "multiple:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "multiple." + instrumentMethod + ".counter";
String description = "multiple double counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Double");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasDoubleGauge()
.points()
.satisfiesExactlyInAnyOrder(assertDoublePoints()));
}
@Test
void longValueCallback() throws Exception {
String instrumentMethod = "longValueCallback";
String thingName = "multiple:type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = "multiple." + instrumentMethod + ".counter";
String description = "multiple double counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Long");
assertThat(meterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
assertThat(metric)
.hasName(instrumentName)
.hasDescription(description)
.hasUnit("1")
.hasLongGauge()
.points()
.satisfiesExactlyInAnyOrder(assertLongPoints()));
}
@SuppressWarnings("unchecked")
private Consumer<DoublePointData>[] assertDoublePoints() {
return Stream.<Consumer<DoublePointData>>of(
point ->
assertThat(point)
.hasValue(123.456)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "0")),
point ->
assertThat(point)
.hasValue(123.456)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "1")),
point ->
assertThat(point)
.hasValue(123.456)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "2")),
point ->
assertThat(point)
.hasValue(123.456)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "3")))
.toArray(Consumer[]::new);
}
@SuppressWarnings("unchecked")
private Consumer<LongPointData>[] assertLongPoints() {
return Stream.<Consumer<LongPointData>>of(
point ->
assertThat(point)
.hasValue(234)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "0")),
point ->
assertThat(point)
.hasValue(234)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "1")),
point ->
assertThat(point)
.hasValue(234)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "2")),
point ->
assertThat(point)
.hasValue(234)
.attributes()
.containsOnly(
attributeEntry("labelOne", "labelOneValue"),
attributeEntry("labelTwo", "3")))
.toArray(Consumer[]::new);
}
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void handlesNulls(boolean isSingle) throws Exception {
String instrumentMethod = "longValueCallback";
String quantity = isSingle ? "single" : "multiple";
String thingName = quantity + ":type=" + instrumentMethod + ".Thing";
MBeanHelper mBeanHelper = registerThings(thingName);
String instrumentName = quantity + "." + instrumentMethod + ".counter";
String description = quantity + " double counter description";
updateWithHelper(mBeanHelper, instrumentMethod, instrumentName, description, "Missing");
assertThat(meterProvider.collectAllMetrics()).isEmpty();
}
@ParameterizedTest
@CsvSource({
"doubleCounter,false,true",
"longCounter,false,true",
"doubleCounterCallback,true,false",
"longCounterCallback,true,false",
"doubleUpDownCounter,false,true",
"longUpDownCounter,false,true",
"doubleUpDownCounterCallback,true,false",
"longUpDownCounterCallback,true,false",
"doubleValueCallback,true,false",
"longValueCallback,true,false",
"doubleHistogram,false,false",
"longHistogram,false,false",
})
void correctlyClassified(String instrumentMethod, boolean isObserver, boolean isCounter) {
Closure<?> instrument = (Closure<?>) Eval.me("otel", otel, "otel.&" + instrumentMethod);
assertThat(InstrumentHelper.instrumentIsObserver(instrument)).isEqualTo(isObserver);
assertThat(InstrumentHelper.instrumentIsCounter(instrument)).isEqualTo(isCounter);
}
MBeanHelper registerThings(String thingName) throws Exception {
for (int i = 0; i < 4; i++) {
Thing thing = new Thing();
String name = thingName + ",thing=" + i;
registeredBeans.add(mbeanServer.registerMBean(thing, new ObjectName(name)));
}
MBeanHelper mBeanHelper =
new MBeanHelper(jmxClient, thingName + ",*", thingName.startsWith("single:"));
mBeanHelper.fetch();
return mBeanHelper;
}
void updateWithHelper(
MBeanHelper mBeanHelper,
String instrumentMethod,
String instrumentName,
String description,
String attribute) {
Closure<?> instrument = (Closure<?>) Eval.me("otel", otel, "otel.&" + instrumentMethod);
Map<String, Closure> labelFuncs = new HashMap<>();
labelFuncs.put("labelOne", (Closure<?>) Eval.me("{ unused -> 'labelOneValue' }"));
labelFuncs.put(
"labelTwo", (Closure<?>) Eval.me("{ mbean -> mbean.name().getKeyProperty('thing') }"));
InstrumentHelper instrumentHelper =
new InstrumentHelper(
mBeanHelper, instrumentName, description, "1", labelFuncs, attribute, instrument);
instrumentHelper.update();
}
public interface ThingMBean {
double getDouble();
long getLong();
}
static class Thing implements ThingMBean {
@Override
public double getDouble() {
return 123.456;
}
@Override
public long getLong() {
return 234;
}
}
}