Skip to content

Commit cb0c862

Browse files
authored
Added CompilationMXBean compilation time metric (#798)
Signed-off-by: Doug Hoard <[email protected]>
1 parent f3bfba1 commit cb0c862

File tree

4 files changed

+149
-5
lines changed

4 files changed

+149
-5
lines changed

simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,4 +254,22 @@ public Double getSampleValue(String name, String[] labelNames, String[] labelVal
254254
return null;
255255
}
256256

257+
/**
258+
* Returns the given value, or null if it doesn't exist.
259+
* <p>
260+
* This is inefficient, and intended only for use in unittests.
261+
*/
262+
public Double getSampleValue(String name, String[] labelNames, String[] labelValues, Predicate<String> sampleNameFilter) {
263+
for (Collector.MetricFamilySamples metricFamilySamples : Collections.list(filteredMetricFamilySamples(sampleNameFilter))) {
264+
for (Collector.MetricFamilySamples.Sample sample : metricFamilySamples.samples) {
265+
if (sample.name.equals(name)
266+
&& Arrays.equals(sample.labelNames.toArray(), labelNames)
267+
&& Arrays.equals(sample.labelValues.toArray(), labelValues)) {
268+
return sample.value;
269+
}
270+
}
271+
}
272+
return null;
273+
}
274+
257275
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.prometheus.client.hotspot;
2+
3+
import io.prometheus.client.Collector;
4+
import io.prometheus.client.CounterMetricFamily;
5+
import io.prometheus.client.GaugeMetricFamily;
6+
import io.prometheus.client.Predicate;
7+
8+
import java.lang.management.ManagementFactory;
9+
import java.lang.management.CompilationMXBean;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
13+
import static io.prometheus.client.SampleNameFilter.ALLOW_ALL;
14+
15+
/**
16+
* Exports metrics about JVM compilation.
17+
* <p>
18+
* Example usage:
19+
* <pre>
20+
* {@code
21+
* new CompilationExports().register();
22+
* }
23+
* </pre>
24+
* Example metrics being exported:
25+
* <pre>
26+
* jvm_compilation_time_ms_total{} 123432
27+
* </pre>
28+
*/
29+
public class CompilationExports extends Collector {
30+
31+
private static final String JVM_COMPILATION_TIME_SECONDS_TOTAL = "jvm_compilation_time_seconds_total";
32+
33+
private final CompilationMXBean compilationMXBean;
34+
35+
public CompilationExports() {
36+
this(ManagementFactory.getCompilationMXBean());
37+
}
38+
39+
public CompilationExports(CompilationMXBean compilationMXBean) {
40+
this.compilationMXBean = compilationMXBean;
41+
}
42+
43+
void addCompilationMetrics(List<MetricFamilySamples> sampleFamilies, Predicate<String> nameFilter) {
44+
// Sanity check in the scenario that a JVM doesn't implement compilation time monitoring
45+
if (compilationMXBean != null && compilationMXBean.isCompilationTimeMonitoringSupported()) {
46+
if (nameFilter.test(JVM_COMPILATION_TIME_SECONDS_TOTAL)) {
47+
sampleFamilies.add(new CounterMetricFamily(
48+
JVM_COMPILATION_TIME_SECONDS_TOTAL,
49+
"The total time in seconds taken for HotSpot class compilation",
50+
compilationMXBean.getTotalCompilationTime() / MILLISECONDS_PER_SECOND));
51+
}
52+
}
53+
}
54+
55+
@Override
56+
public List<MetricFamilySamples> collect() {
57+
return collect(null);
58+
}
59+
60+
@Override
61+
public List<MetricFamilySamples> collect(Predicate<String> nameFilter) {
62+
List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>(1);
63+
addCompilationMetrics(mfs, nameFilter == null ? ALLOW_ALL : nameFilter);
64+
return mfs;
65+
}
66+
}

simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* </pre>
1717
*/
1818
public class DefaultExports {
19+
1920
private static boolean initialized = false;
2021

2122
/**
@@ -34,14 +35,14 @@ public static synchronized void initialize() {
3435
* Register the default Hotspot collectors with the given registry.
3536
*/
3637
public static void register(CollectorRegistry registry) {
37-
new StandardExports().register(registry);
38-
new MemoryPoolsExports().register(registry);
39-
new MemoryAllocationExports().register(registry);
4038
new BufferPoolsExports().register(registry);
39+
new ClassLoadingExports().register(registry);
40+
new CompilationExports().register(registry);
4141
new GarbageCollectorExports().register(registry);
42+
new MemoryAllocationExports().register(registry);
43+
new MemoryPoolsExports().register(registry);
44+
new StandardExports().register(registry);
4245
new ThreadExports().register(registry);
43-
new ClassLoadingExports().register(registry);
4446
new VersionInfoExports().register(registry);
4547
}
46-
4748
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package io.prometheus.client.hotspot;
2+
3+
import io.prometheus.client.CollectorRegistry;
4+
import io.prometheus.client.SampleNameFilter;
5+
import org.junit.Before;
6+
import org.junit.Test;
7+
import org.mockito.Mockito;
8+
9+
import java.lang.management.CompilationMXBean;
10+
11+
import static org.junit.Assert.assertEquals;
12+
import static org.junit.Assert.assertNull;
13+
import static org.mockito.Mockito.when;
14+
15+
public class CompilationExportsTest {
16+
17+
private CompilationMXBean mockCompilationsBean = Mockito.mock(CompilationMXBean.class);
18+
private CollectorRegistry registry = new CollectorRegistry();
19+
private CompilationExports collectorUnderTest;
20+
21+
private static final String[] EMPTY_LABEL = new String[0];
22+
23+
@Before
24+
public void setUp() {
25+
when(mockCompilationsBean.getTotalCompilationTime()).thenReturn(10000l);
26+
when(mockCompilationsBean.isCompilationTimeMonitoringSupported()).thenReturn(true);
27+
collectorUnderTest = new CompilationExports(mockCompilationsBean).register(registry);
28+
}
29+
30+
@Test
31+
public void testCompilationExports() {
32+
assertEquals(
33+
10.0,
34+
registry.getSampleValue(
35+
"jvm_compilation_time_seconds_total", EMPTY_LABEL, EMPTY_LABEL),
36+
.0000001);
37+
}
38+
39+
@Test
40+
public void testCompilationExportsWithFilter() {
41+
assertEquals(
42+
10.0,
43+
registry.getSampleValue(
44+
"jvm_compilation_time_seconds_total", EMPTY_LABEL, EMPTY_LABEL, SampleNameFilter.ALLOW_ALL),
45+
.0000001);
46+
}
47+
48+
@Test
49+
public void testCompilationExportsFiltered() {
50+
SampleNameFilter sampleNameFilter =
51+
new SampleNameFilter.Builder()
52+
.nameMustNotBeEqualTo("jvm_compilation_time_seconds_total")
53+
.build();
54+
55+
assertNull(
56+
registry.getSampleValue(
57+
"jvm_compilation_time_seconds_total", EMPTY_LABEL, EMPTY_LABEL, sampleNameFilter));
58+
}
59+
}

0 commit comments

Comments
 (0)