Skip to content

Commit

Permalink
[jmx-scraper] fix JVM units + simplify tests (#1593)
Browse files Browse the repository at this point in the history
  • Loading branch information
SylvainJuge authored Dec 11, 2024
1 parent 10efe16 commit fa217e5
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ void endToEnd() {
"Metaspace",
"Par Survivor Space");
waitAndAssertMetrics(
metric -> assertGauge(metric, "jvm.classes.loaded", "number of loaded classes", "1"),
metric -> assertGauge(metric, "jvm.classes.loaded", "number of loaded classes", "{class}"),
metric ->
assertTypedSum(
metric,
"jvm.gc.collections.count",
"total number of collections that have occurred",
"1",
"{collection}",
Arrays.asList("ConcurrentMarkSweep", "ParNew")),
metric ->
assertTypedSum(
Expand All @@ -46,27 +46,27 @@ void endToEnd() {
"the approximate accumulated collection elapsed time in milliseconds",
"ms",
Arrays.asList("ConcurrentMarkSweep", "ParNew")),
metric -> assertGauge(metric, "jvm.memory.heap.committed", "current heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.heap.init", "current heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.heap.max", "current heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.heap.used", "current heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.heap.committed", "current heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.heap.init", "current heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.heap.max", "current heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.heap.used", "current heap usage", "By"),
metric ->
assertGauge(metric, "jvm.memory.nonheap.committed", "current non-heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.nonheap.init", "current non-heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.nonheap.max", "current non-heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.nonheap.used", "current non-heap usage", "by"),
assertGauge(metric, "jvm.memory.nonheap.committed", "current non-heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.nonheap.init", "current non-heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.nonheap.max", "current non-heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.nonheap.used", "current non-heap usage", "By"),
metric ->
assertTypedGauge(
metric, "jvm.memory.pool.committed", "current memory pool usage", "by", gcLabels),
metric, "jvm.memory.pool.committed", "current memory pool usage", "By", gcLabels),
metric ->
assertTypedGauge(
metric, "jvm.memory.pool.init", "current memory pool usage", "by", gcLabels),
metric, "jvm.memory.pool.init", "current memory pool usage", "By", gcLabels),
metric ->
assertTypedGauge(
metric, "jvm.memory.pool.max", "current memory pool usage", "by", gcLabels),
metric, "jvm.memory.pool.max", "current memory pool usage", "By", gcLabels),
metric ->
assertTypedGauge(
metric, "jvm.memory.pool.used", "current memory pool usage", "by", gcLabels),
metric -> assertGauge(metric, "jvm.threads.count", "number of threads", "1"));
metric, "jvm.memory.pool.used", "current memory pool usage", "By", gcLabels),
metric -> assertGauge(metric, "jvm.threads.count", "number of threads", "{thread}"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -380,13 +380,14 @@ void endToEnd() {
List<Consumer<Metric>> assertions = new ArrayList<>(kafkaBrokerAssertions());
assertions.addAll(
Arrays.asList(
metric -> assertGauge(metric, "jvm.classes.loaded", "number of loaded classes", "1"),
metric ->
assertGauge(metric, "jvm.classes.loaded", "number of loaded classes", "{class}"),
metric ->
assertTypedSum(
metric,
"jvm.gc.collections.count",
"total number of collections that have occurred",
"1",
"{collection}",
Arrays.asList("G1 Young Generation", "G1 Old Generation")),
metric ->
assertTypedSum(
Expand All @@ -396,36 +397,36 @@ void endToEnd() {
"ms",
Arrays.asList("G1 Young Generation", "G1 Old Generation")),
metric ->
assertGauge(metric, "jvm.memory.heap.committed", "current heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.heap.init", "current heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.heap.max", "current heap usage", "by"),
metric -> assertGauge(metric, "jvm.memory.heap.used", "current heap usage", "by"),
assertGauge(metric, "jvm.memory.heap.committed", "current heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.heap.init", "current heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.heap.max", "current heap usage", "By"),
metric -> assertGauge(metric, "jvm.memory.heap.used", "current heap usage", "By"),
metric ->
assertGauge(
metric, "jvm.memory.nonheap.committed", "current non-heap usage", "by"),
metric, "jvm.memory.nonheap.committed", "current non-heap usage", "By"),
metric ->
assertGauge(metric, "jvm.memory.nonheap.init", "current non-heap usage", "by"),
assertGauge(metric, "jvm.memory.nonheap.init", "current non-heap usage", "By"),
metric ->
assertGauge(metric, "jvm.memory.nonheap.max", "current non-heap usage", "by"),
assertGauge(metric, "jvm.memory.nonheap.max", "current non-heap usage", "By"),
metric ->
assertGauge(metric, "jvm.memory.nonheap.used", "current non-heap usage", "by"),
assertGauge(metric, "jvm.memory.nonheap.used", "current non-heap usage", "By"),
metric ->
assertTypedGauge(
metric,
"jvm.memory.pool.committed",
"current memory pool usage",
"by",
"By",
gcLabels),
metric ->
assertTypedGauge(
metric, "jvm.memory.pool.init", "current memory pool usage", "by", gcLabels),
metric, "jvm.memory.pool.init", "current memory pool usage", "By", gcLabels),
metric ->
assertTypedGauge(
metric, "jvm.memory.pool.max", "current memory pool usage", "by", gcLabels),
metric, "jvm.memory.pool.max", "current memory pool usage", "By", gcLabels),
metric ->
assertTypedGauge(
metric, "jvm.memory.pool.used", "current memory pool usage", "by", gcLabels),
metric -> assertGauge(metric, "jvm.threads.count", "number of threads", "1")));
metric, "jvm.memory.pool.used", "current memory pool usage", "By", gcLabels),
metric -> assertGauge(metric, "jvm.threads.count", "number of threads", "{thread}")));

waitAndAssertMetrics(assertions);
}
Expand Down
12 changes: 6 additions & 6 deletions jmx-metrics/src/main/resources/target-systems/jvm.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

def classLoading = otel.mbean("java.lang:type=ClassLoading")
otel.instrument(classLoading, "jvm.classes.loaded", "number of loaded classes",
"1", "LoadedClassCount", otel.&longValueCallback)
"{class}", "LoadedClassCount", otel.&longValueCallback)

def garbageCollector = otel.mbeans("java.lang:type=GarbageCollector,*")
otel.instrument(garbageCollector, "jvm.gc.collections.count", "total number of collections that have occurred",
"1", ["name" : { mbean -> mbean.name().getKeyProperty("name") }],
"{collection}", ["name" : { mbean -> mbean.name().getKeyProperty("name") }],
"CollectionCount", otel.&longCounterCallback)
otel.instrument(garbageCollector, "jvm.gc.collections.elapsed",
"the approximate accumulated collection elapsed time in milliseconds", "ms",
Expand All @@ -29,15 +29,15 @@ otel.instrument(garbageCollector, "jvm.gc.collections.elapsed",

def memory = otel.mbean("java.lang:type=Memory")
otel.instrument(memory, "jvm.memory.heap", "current heap usage",
"by", "HeapMemoryUsage", otel.&longValueCallback)
"By", "HeapMemoryUsage", otel.&longValueCallback)
otel.instrument(memory, "jvm.memory.nonheap", "current non-heap usage",
"by", "NonHeapMemoryUsage", otel.&longValueCallback)
"By", "NonHeapMemoryUsage", otel.&longValueCallback)

def memoryPool = otel.mbeans("java.lang:type=MemoryPool,*")
otel.instrument(memoryPool, "jvm.memory.pool", "current memory pool usage",
"by", ["name" : { mbean -> mbean.name().getKeyProperty("name") }],
"By", ["name" : { mbean -> mbean.name().getKeyProperty("name") }],
"Usage", otel.&longValueCallback)

def threading = otel.mbean("java.lang:type=Threading")
otel.instrument(threading, "jvm.threads.count", "number of threads",
"1", "ThreadCount", otel.&longValueCallback)
"{thread}", "ThreadCount", otel.&longValueCallback)
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@
import io.opentelemetry.proto.metrics.v1.Metric;
import io.opentelemetry.proto.metrics.v1.NumberDataPoint;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.assertj.core.api.AbstractAssert;
Expand Down Expand Up @@ -199,31 +196,6 @@ private MetricAssert checkDataPoints(Consumer<List<NumberDataPoint>> listConsume
return this;
}

// TODO: To be removed and calls will be replaced with hasDataPointsWithAttributes()
@CanIgnoreReturnValue
public MetricAssert hasTypedDataPoints(Collection<String> types) {
return checkDataPoints(
dataPoints -> {
dataPointsCommonCheck(dataPoints);

Set<String> foundValues = new HashSet<>();
for (NumberDataPoint dataPoint : dataPoints) {
List<KeyValue> attributes = dataPoint.getAttributesList();

info.description(
"expected exactly one 'name' attribute for typed data point in metric '%s'",
actual.getName());
iterables.assertHasSize(info, attributes, 1);

objects.assertEqual(info, attributes.get(0).getKey(), "name");
foundValues.add(attributes.get(0).getValue().getStringValue());
}
info.description(
"missing or unexpected type attribute for metric '%s'", actual.getName());
iterables.assertContainsExactlyInAnyOrder(info, foundValues, types.toArray());
});
}

private void dataPointsCommonCheck(List<NumberDataPoint> dataPoints) {
info.description("unable to retrieve data points from metric '%s'", actual.getName());
objects.assertNotNull(info, dataPoints);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@

package io.opentelemetry.contrib.jmxscraper.target_systems;

import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attribute;
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeGroup;

import io.opentelemetry.contrib.jmxscraper.JmxScraperContainer;
import io.opentelemetry.contrib.jmxscraper.TestAppContainer;
import io.opentelemetry.contrib.jmxscraper.assertions.AttributeMatcherGroup;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;

Expand All @@ -34,33 +36,34 @@ protected JmxScraperContainer customizeScraperContainer(
@Override
protected MetricsVerifier createMetricsVerifier() {
// those values depend on the JVM GC configured
List<String> gcLabels =
Arrays.asList(
AttributeMatcherGroup[] memoryAttributes =
nameAttributeMatchers(
"Code Cache",
"PS Eden Space",
"PS Old Gen",
"Metaspace",
"Compressed Class Space",
"PS Survivor Space");
List<String> gcCollectionLabels = Arrays.asList("PS MarkSweep", "PS Scavenge");
AttributeMatcherGroup[] gcAlgorithmAttributes =
nameAttributeMatchers("PS MarkSweep", "PS Scavenge");

return MetricsVerifier.create()
.add(
"jvm.classes.loaded",
metric ->
metric
.hasDescription("number of loaded classes")
.hasUnit("1")
.hasUnit("{class}")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.gc.collections.count",
metric ->
metric
.hasDescription("total number of collections that have occurred")
.hasUnit("1")
.hasUnit("{collection}")
.isCounter()
.hasTypedDataPoints(gcCollectionLabels))
.hasDataPointsWithAttributes(gcAlgorithmAttributes))
.add(
"jvm.gc.collections.elapsed",
metric ->
Expand All @@ -69,110 +72,118 @@ protected MetricsVerifier createMetricsVerifier() {
"the approximate accumulated collection elapsed time in milliseconds")
.hasUnit("ms")
.isCounter()
.hasTypedDataPoints(gcCollectionLabels))
.hasDataPointsWithAttributes(gcAlgorithmAttributes))
.add(
"jvm.memory.heap.committed",
metric ->
metric
.hasDescription("current heap usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.memory.heap.init",
metric ->
metric
.hasDescription("current heap usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.memory.heap.max",
metric ->
metric
.hasDescription("current heap usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.memory.heap.used",
metric ->
metric
.hasDescription("current heap usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.memory.nonheap.committed",
metric ->
metric
.hasDescription("current non-heap usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.memory.nonheap.init",
metric ->
metric
.hasDescription("current non-heap usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.memory.nonheap.max",
metric ->
metric
.hasDescription("current non-heap usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.memory.nonheap.used",
metric ->
metric
.hasDescription("current non-heap usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasDataPointsWithoutAttributes())
.add(
"jvm.memory.pool.committed",
metric ->
metric
.hasDescription("current memory pool usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasTypedDataPoints(gcLabels))
.hasDataPointsWithAttributes(memoryAttributes))
.add(
"jvm.memory.pool.init",
metric ->
metric
.hasDescription("current memory pool usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasTypedDataPoints(gcLabels))
.hasDataPointsWithAttributes(memoryAttributes))
.add(
"jvm.memory.pool.max",
metric ->
metric
.hasDescription("current memory pool usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasTypedDataPoints(gcLabels))
.hasDataPointsWithAttributes(memoryAttributes))
.add(
"jvm.memory.pool.used",
metric ->
metric
.hasDescription("current memory pool usage")
.hasUnit("by")
.hasUnit("By")
.isGauge()
.hasTypedDataPoints(gcLabels))
.hasDataPointsWithAttributes(memoryAttributes))
.add(
"jvm.threads.count",
metric ->
metric
.hasDescription("number of threads")
.hasUnit("1")
.hasUnit("{thread}")
.isGauge()
.hasDataPointsWithoutAttributes());
}

private static AttributeMatcherGroup[] nameAttributeMatchers(String... values) {
AttributeMatcherGroup[] groups = new AttributeMatcherGroup[values.length];
for (int i = 0; i < values.length; i++) {
groups[i] = attributeGroup(attribute("name", values[i]));
}
return groups;
}
}
Loading

0 comments on commit fa217e5

Please sign in to comment.