diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java index 79cd6ed5e..ee041cbd1 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java @@ -42,6 +42,7 @@ public static void register(CollectorRegistry registry) { new ThreadExports().register(registry); new ClassLoadingExports().register(registry); new VersionInfoExports().register(registry); + new SafepointExports().register(registry); } } diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/SafepointExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/SafepointExports.java new file mode 100644 index 000000000..6f1387cef --- /dev/null +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/SafepointExports.java @@ -0,0 +1,63 @@ +package io.prometheus.client.hotspot; + +import io.prometheus.client.Collector; +import io.prometheus.client.CounterMetricFamily; +import io.prometheus.client.SummaryMetricFamily; +import sun.management.HotspotRuntimeMBean; +import sun.management.ManagementFactoryHelper; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Exports metrics about JVM Safepoints. + *

+ * Example usage: + *

+ * {@code
+ *   new SafepointExports().register();
+ * }
+ * 
+ * Example metrics being exported: + *
+ *   jvm_safepoint_seconds_count{} 200
+ *   jvm_safepoint_seconds_sum{} 6.7
+ *   jvm_safepoint_sync_time_seconds{} 6.7
+ * 
+ */ +public class SafepointExports extends Collector { + private final HotspotRuntimeMBean hotspotRuntimeMBean; + + public SafepointExports() { + this(ManagementFactoryHelper.getHotspotRuntimeMBean()); + } + + SafepointExports(HotspotRuntimeMBean hotspotRuntimeMBean) { + this.hotspotRuntimeMBean = hotspotRuntimeMBean; + } + + public List collect() { + SummaryMetricFamily safepoint = new SummaryMetricFamily( + "jvm_safepoint_seconds", + "The accumulated time spent at safepoints in seconds. This is the accumulated elapsed time that the application has been stopped for safepoint operations. (count: The number of safepoints taken place since the JVM started.", + Collections.EMPTY_LIST); + + safepoint.addMetric( + Collections.EMPTY_LIST, + hotspotRuntimeMBean.getSafepointCount(), + hotspotRuntimeMBean.getTotalSafepointTime() / MILLISECONDS_PER_SECOND); + + CounterMetricFamily safepointSyncTime = new CounterMetricFamily( + "jvm_safepoint_sync_time_seconds", + "The accumulated time spent getting to safepoints in seconds.", + hotspotRuntimeMBean.getSafepointSyncTime() / MILLISECONDS_PER_SECOND); + + List mfs = new ArrayList(); + mfs.add(safepoint); + mfs.add(safepointSyncTime); + + return mfs; + } +} diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/SafepointExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/SafepointExportsTest.java new file mode 100644 index 000000000..469683c13 --- /dev/null +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/SafepointExportsTest.java @@ -0,0 +1,47 @@ +package io.prometheus.client.hotspot; + +import io.prometheus.client.CollectorRegistry; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import sun.management.HotspotRuntimeMBean; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +public class SafepointExportsTest { + + private HotspotRuntimeMBean mockHotspotRuntimeBean = Mockito.mock(HotspotRuntimeMBean.class); + private CollectorRegistry registry = new CollectorRegistry(); + private SafepointExports collectorUnderTest; + + private static final String[] EMPTY_LABEL = new String[0]; + + + @Before + public void setUp() { + when(mockHotspotRuntimeBean.getSafepointCount()).thenReturn(300L); + when(mockHotspotRuntimeBean.getTotalSafepointTime()).thenReturn(13L); + when(mockHotspotRuntimeBean.getSafepointSyncTime()).thenReturn(31L); + collectorUnderTest = new SafepointExports(mockHotspotRuntimeBean).register(registry); + } + + @Test + public void testSafepoints() { + assertEquals( + 300L, + registry.getSampleValue( + "jvm_safepoint_seconds_count", EMPTY_LABEL, EMPTY_LABEL), + .0000001); + assertEquals( + 0.013, + registry.getSampleValue( + "jvm_safepoint_seconds_sum", EMPTY_LABEL, EMPTY_LABEL), + .0000001); + assertEquals( + 0.031, + registry.getSampleValue( + "jvm_safepoint_sync_time_seconds", EMPTY_LABEL, EMPTY_LABEL), + .0000001); + } +}