diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java index ec41ec8ad..3bd39a59f 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java @@ -5,28 +5,34 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.model.registry.PrometheusRegistry; - -import javax.management.Notification; -import javax.management.NotificationEmitter; -import javax.management.NotificationListener; -import javax.management.openmbean.CompositeData; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import javax.management.openmbean.CompositeData; /** - * JVM memory allocation metrics. The {@link JvmMemoryPoolAllocationMetrics} are registered as part of the {@link JvmMetrics} like this: + * JVM memory allocation metrics. The {@link JvmMemoryPoolAllocationMetrics} are registered as part + * of the {@link JvmMetrics} like this: + * *
{@code - * JvmMetrics.builder().register(); + * JvmMetrics.builder().register(); * }- * However, if you want only the {@link JvmMemoryPoolAllocationMetrics} you can also register them directly: + * + * However, if you want only the {@link JvmMemoryPoolAllocationMetrics} you can also register them + * directly: + * *
{@code - * JvmMemoryAllocationMetrics.builder().register(); + * JvmMemoryAllocationMetrics.builder().register(); * }+ * * Example metrics being exported: + * *
* # HELP jvm_memory_pool_allocated_bytes_total Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously. * # TYPE jvm_memory_pool_allocated_bytes_total counter @@ -40,129 +46,134 @@ */ public class JvmMemoryPoolAllocationMetrics { - private static final String JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL = "jvm_memory_pool_allocated_bytes_total"; + private static final String JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL = + "jvm_memory_pool_allocated_bytes_total"; + + private final ListgarbageCollectorBeans; + + private JvmMemoryPoolAllocationMetrics( + List garbageCollectorBeans, PrometheusProperties config) { + this.garbageCollectorBeans = garbageCollectorBeans; + } + + private void register(PrometheusRegistry registry) { + + Counter allocatedCounter = + Counter.builder() + .name(JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL) + .help( + "Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.") + .labelNames("pool") + .register(registry); + + AllocationCountingNotificationListener listener = + new AllocationCountingNotificationListener(allocatedCounter); + for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorBeans) { + if (garbageCollectorMXBean instanceof NotificationEmitter) { + ((NotificationEmitter) garbageCollectorMXBean) + .addNotificationListener(listener, null, null); + } + } + } + + static class AllocationCountingNotificationListener implements NotificationListener { - private final List garbageCollectorBeans; + private final Map lastMemoryUsage = new HashMap<>(); + private final Counter counter; - private JvmMemoryPoolAllocationMetrics(List garbageCollectorBeans, PrometheusProperties config) { - this.garbageCollectorBeans = garbageCollectorBeans; + AllocationCountingNotificationListener(Counter counter) { + this.counter = counter; } - private void register(PrometheusRegistry registry) { + @Override + public synchronized void handleNotification(Notification notification, Object handback) { + GarbageCollectionNotificationInfo info = + GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); + GcInfo gcInfo = info.getGcInfo(); + Map memoryUsageBeforeGc = gcInfo.getMemoryUsageBeforeGc(); + Map memoryUsageAfterGc = gcInfo.getMemoryUsageAfterGc(); + for (Map.Entry entry : memoryUsageBeforeGc.entrySet()) { + String memoryPool = entry.getKey(); + long before = entry.getValue().getUsed(); + long after = memoryUsageAfterGc.get(memoryPool).getUsed(); + handleMemoryPool(memoryPool, before, after); + } + } - Counter allocatedCounter = Counter.builder() - .name(JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL) - .help("Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.") - .labelNames("pool") - .register(registry); + // Visible for testing + void handleMemoryPool(String memoryPool, long before, long after) { + /* + * Calculate increase in the memory pool by comparing memory used + * after last GC, before this GC, and after this GC. + * See ascii illustration below. + * Make sure to count only increases and ignore decreases. + * (Typically a pool will only increase between GCs or during GCs, not both. + * E.g. eden pools between GCs. Survivor and old generation pools during GCs.) + * + * |<-- diff1 -->|<-- diff2 -->| + * Timeline: |-- last GC --| |---- GC -----| + * ___^__ ___^____ ___^___ + * Mem. usage vars: / last \ / before \ / after \ + */ + + // Get last memory usage after GC and remember memory used after for next time + long last = getAndSet(lastMemoryUsage, memoryPool, after); + // Difference since last GC + long diff1 = before - last; + // Difference during this GC + long diff2 = after - before; + // Make sure to only count increases + if (diff1 < 0) { + diff1 = 0; + } + if (diff2 < 0) { + diff2 = 0; + } + long increase = diff1 + diff2; + if (increase > 0) { + counter.labelValues(memoryPool).inc(increase); + } + } - AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(allocatedCounter); - for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorBeans) { - if (garbageCollectorMXBean instanceof NotificationEmitter) { - ((NotificationEmitter) garbageCollectorMXBean).addNotificationListener(listener, null, null); - } - } + private static long getAndSet(Map map, String key, long value) { + Long last = map.put(key, value); + return last == null ? 0 : last; } + } + + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private List garbageCollectorBeans; - static class AllocationCountingNotificationListener implements NotificationListener { - - private final Map lastMemoryUsage = new HashMap<>(); - private final Counter counter; - - AllocationCountingNotificationListener(Counter counter) { - this.counter = counter; - } - - @Override - public synchronized void handleNotification(Notification notification, Object handback) { - GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); - GcInfo gcInfo = info.getGcInfo(); - Map memoryUsageBeforeGc = gcInfo.getMemoryUsageBeforeGc(); - Map memoryUsageAfterGc = gcInfo.getMemoryUsageAfterGc(); - for (Map.Entry entry : memoryUsageBeforeGc.entrySet()) { - String memoryPool = entry.getKey(); - long before = entry.getValue().getUsed(); - long after = memoryUsageAfterGc.get(memoryPool).getUsed(); - handleMemoryPool(memoryPool, before, after); - } - } - - // Visible for testing - void handleMemoryPool(String memoryPool, long before, long after) { - /* - * Calculate increase in the memory pool by comparing memory used - * after last GC, before this GC, and after this GC. - * See ascii illustration below. - * Make sure to count only increases and ignore decreases. - * (Typically a pool will only increase between GCs or during GCs, not both. - * E.g. eden pools between GCs. Survivor and old generation pools during GCs.) - * - * |<-- diff1 -->|<-- diff2 -->| - * Timeline: |-- last GC --| |---- GC -----| - * ___^__ ___^____ ___^___ - * Mem. usage vars: / last \ / before \ / after \ - */ - - // Get last memory usage after GC and remember memory used after for next time - long last = getAndSet(lastMemoryUsage, memoryPool, after); - // Difference since last GC - long diff1 = before - last; - // Difference during this GC - long diff2 = after - before; - // Make sure to only count increases - if (diff1 < 0) { - diff1 = 0; - } - if (diff2 < 0) { - diff2 = 0; - } - long increase = diff1 + diff2; - if (increase > 0) { - counter.labelValues(memoryPool).inc(increase); - } - } - - private static long getAndSet(Map map, String key, long value) { - Long last = map.put(key, value); - return last == null ? 0 : last; - } + private Builder(PrometheusProperties config) { + this.config = config; } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + /** Package private. For testing only. */ + Builder withGarbageCollectorBeans(List garbageCollectorBeans) { + this.garbageCollectorBeans = garbageCollectorBeans; + return this; } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + public void register() { + register(PrometheusRegistry.defaultRegistry); } - public static class Builder { - - private final PrometheusProperties config; - private List garbageCollectorBeans; - - private Builder(PrometheusProperties config) { - this.config = config; - } - - /** - * Package private. For testing only. - */ - Builder withGarbageCollectorBeans(List garbageCollectorBeans) { - this.garbageCollectorBeans = garbageCollectorBeans; - return this; - } - - public void register() { - register(PrometheusRegistry.defaultRegistry); - } - - public void register(PrometheusRegistry registry) { - List garbageCollectorBeans = this.garbageCollectorBeans; - if (garbageCollectorBeans == null) { - garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans(); - } - new JvmMemoryPoolAllocationMetrics(garbageCollectorBeans, config).register(registry); - } + public void register(PrometheusRegistry registry) { + List garbageCollectorBeans = this.garbageCollectorBeans; + if (garbageCollectorBeans == null) { + garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans(); + } + new JvmMemoryPoolAllocationMetrics(garbageCollectorBeans, config).register(registry); } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java index 54d937688..0f5a56eee 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java @@ -2,67 +2,70 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; - import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** * Registers all JVM metrics. Example usage: + * * {@code - * JvmMetrics.builder().register(); + * JvmMetrics.builder().register(); * }*/ public class JvmMetrics { - private static final SetREGISTERED = ConcurrentHashMap.newKeySet(); - public static Builder builder() { - return new Builder(PrometheusProperties.get()); - } + private static final Set REGISTERED = ConcurrentHashMap.newKeySet(); - // Note: Currently there is no configuration for JVM metrics, so it doesn't matter whether you pass a config or not. - // However, we will add config options in the future, like whether you want to use Prometheus naming conventions - // or OpenTelemetry semantic conventions for JVM metrics. - public static Builder builder(PrometheusProperties config) { - return new Builder(config); - } + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } - public static class Builder { + // Note: Currently there is no configuration for JVM metrics, so it doesn't matter whether you + // pass a config or not. + // However, we will add config options in the future, like whether you want to use Prometheus + // naming conventions + // or OpenTelemetry semantic conventions for JVM metrics. + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } - private final PrometheusProperties config; + public static class Builder { - private Builder(PrometheusProperties config) { - this.config = config; - } + private final PrometheusProperties config; - /** - * Register all JVM metrics with the default registry. - * - * It's safe to call this multiple times, only the first call will register the metrics, all subsequent calls - * will be ignored. - */ - public void register() { - register(PrometheusRegistry.defaultRegistry); - } + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Register all JVM metrics with the default registry. + * + *
It's safe to call this multiple times, only the first call will register the metrics, all + * subsequent calls will be ignored. + */ + public void register() { + register(PrometheusRegistry.defaultRegistry); + } - /** - * Register all JVM metrics with the {@code registry}. - *
- * It's safe to call this multiple times, only the first call will register the metrics, all subsequent calls - * will be ignored. - */ - public void register(PrometheusRegistry registry) { - if (REGISTERED.add(registry)) { - JvmThreadsMetrics.builder(config).register(registry); - JvmBufferPoolMetrics.builder(config).register(registry); - JvmClassLoadingMetrics.builder(config).register(registry); - JvmCompilationMetrics.builder(config).register(registry); - JvmGarbageCollectorMetrics.builder(config).register(registry); - JvmMemoryPoolAllocationMetrics.builder(config).register(registry); - JvmMemoryMetrics.builder(config).register(registry); - JvmNativeMemoryMetrics.builder(config).register(registry); - JvmRuntimeInfoMetric.builder(config).register(registry); - ProcessMetrics.builder(config).register(registry); - } - } + /** + * Register all JVM metrics with the {@code registry}. + * + *
It's safe to call this multiple times, only the first call will register the metrics, all + * subsequent calls will be ignored. + */ + public void register(PrometheusRegistry registry) { + if (REGISTERED.add(registry)) { + JvmThreadsMetrics.builder(config).register(registry); + JvmBufferPoolMetrics.builder(config).register(registry); + JvmClassLoadingMetrics.builder(config).register(registry); + JvmCompilationMetrics.builder(config).register(registry); + JvmGarbageCollectorMetrics.builder(config).register(registry); + JvmMemoryPoolAllocationMetrics.builder(config).register(registry); + JvmMemoryMetrics.builder(config).register(registry); + JvmNativeMemoryMetrics.builder(config).register(registry); + JvmRuntimeInfoMetric.builder(config).register(registry); + ProcessMetrics.builder(config).register(registry); + } } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java index 8207e6cb0..e350568ac 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java @@ -4,34 +4,41 @@ import io.prometheus.metrics.core.metrics.GaugeWithCallback; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.Unit; - -import javax.management.InstanceNotFoundException; -import javax.management.MBeanException; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.management.ReflectionException; import java.lang.management.ManagementFactory; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.ReflectionException; /** - * JVM native memory. JVM native memory tracking is disabled by default. You need to enable it by starting your JVM with this flag: + * JVM native memory. JVM native memory tracking is disabled by default. You need to enable it by + * starting your JVM with this flag: + * *
-XX:NativeMemoryTracking=summary+ * + *When native memory tracking is disabled the metrics are not registered either. + * *
- * When native memory tracking is disabled the metrics are not registered either. - *
- *
- * The {@link JvmNativeMemoryMetrics} are registered as part of the {@link JvmMetrics} like this: + * + *
The {@link JvmNativeMemoryMetrics} are registered as part of the {@link JvmMetrics} like this: + * *
{@code - * JvmMetrics.builder().register(); + * JvmMetrics.builder().register(); * }+ * * However, if you want only the {@link JvmNativeMemoryMetrics} you can also register them directly: + * *{@code - * JvmNativeMemoryMetrics.builder().register(); + * JvmNativeMemoryMetrics.builder().register(); * }+ * * Example metrics being exported: + * ** # HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now. * # TYPE jvm_native_memory_committed_bytes gauge @@ -79,13 +86,13 @@ */ public class JvmNativeMemoryMetrics { private static final String JVM_NATIVE_MEMORY_RESERVED_BYTES = "jvm_native_memory_reserved_bytes"; - private static final String JVM_NATIVE_MEMORY_COMMITTED_BYTES = "jvm_native_memory_committed_bytes"; + private static final String JVM_NATIVE_MEMORY_COMMITTED_BYTES = + "jvm_native_memory_committed_bytes"; - private static final Pattern pattern = Pattern.compile("\\s*([A-Z][A-Za-z\\s]*[A-Za-z]+).*reserved=(\\d+), committed=(\\d+)"); + private static final Pattern pattern = + Pattern.compile("\\s*([A-Z][A-Za-z\\s]*[A-Za-z]+).*reserved=(\\d+), committed=(\\d+)"); - /** - * Package private. For testing only. - */ + /** Package private. For testing only. */ static final AtomicBoolean isEnabled = new AtomicBoolean(true); private final PrometheusProperties config; @@ -102,7 +109,8 @@ private void register(PrometheusRegistry registry) { if (isEnabled.get()) { GaugeWithCallback.builder(config) .name(JVM_NATIVE_MEMORY_RESERVED_BYTES) - .help("Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.") + .help( + "Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.") .unit(Unit.BYTES) .labelNames("pool") .callback(makeCallback(true)) @@ -110,7 +118,8 @@ private void register(PrometheusRegistry registry) { GaugeWithCallback.builder(config) .name(JVM_NATIVE_MEMORY_COMMITTED_BYTES) - .help("Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.") + .help( + "Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.") .unit(Unit.BYTES) .labelNames("pool") .callback(makeCallback(false)) @@ -125,7 +134,8 @@ private ConsumermakeCallback(Boolean reserved) { Matcher matcher = pattern.matcher(summary); while (matcher.find()) { String category = matcher.group(1); - long value = reserved ? Long.parseLong(matcher.group(2)) : Long.parseLong(matcher.group(3)); + long value = + reserved ? Long.parseLong(matcher.group(2)) : Long.parseLong(matcher.group(3)); callback.call(value, category); } } @@ -160,12 +170,17 @@ static class DefaultPlatformMBeanServerAdapter implements PlatformMBeanServerAda @Override public String vmNativeMemorySummaryInBytes() { try { - return (String) ManagementFactory.getPlatformMBeanServer().invoke( - new ObjectName("com.sun.management:type=DiagnosticCommand"), - "vmNativeMemory", - new Object[]{new String[]{"summary", "scale=B"}}, - new String[]{"[Ljava.lang.String;"}); - } catch (ReflectionException | MalformedObjectNameException | InstanceNotFoundException | MBeanException e) { + return (String) + ManagementFactory.getPlatformMBeanServer() + .invoke( + new ObjectName("com.sun.management:type=DiagnosticCommand"), + "vmNativeMemory", + new Object[] {new String[] {"summary", "scale=B"}}, + new String[] {"[Ljava.lang.String;"}); + } catch (ReflectionException + | MalformedObjectNameException + | InstanceNotFoundException + | MBeanException e) { throw new IllegalStateException("Native memory tracking is not enabled", e); } } @@ -188,9 +203,7 @@ private Builder(PrometheusProperties config) { this(config, new DefaultPlatformMBeanServerAdapter()); } - /** - * Package private. For testing only. - */ + /** Package private. For testing only. */ Builder(PrometheusProperties config, PlatformMBeanServerAdapter adapter) { this.config = config; this.adapter = adapter; diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java index afeff66d8..8725dcbbf 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java @@ -4,7 +4,6 @@ import io.prometheus.metrics.core.metrics.CounterWithCallback; import io.prometheus.metrics.core.metrics.GaugeWithCallback; import io.prometheus.metrics.model.registry.PrometheusRegistry; - import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; @@ -13,15 +12,21 @@ import java.util.Map; /** - * JVM Thread metrics. The {@link JvmThreadsMetrics} are registered as part of the {@link JvmMetrics} like this: + * JVM Thread metrics. The {@link JvmThreadsMetrics} are registered as part of the {@link + * JvmMetrics} like this: + * * {@code - * JvmMetrics.builder().register(); + * JvmMetrics.builder().register(); * }+ * * However, if you want only the {@link JvmThreadsMetrics} you can also register them directly: + * *{@code - * JvmThreadMetrics.builder().register(); + * JvmThreadMetrics.builder().register(); * }+ * * Example metrics being exported: + * ** # HELP jvm_threads_current Current thread count of a JVM * # TYPE jvm_threads_current gauge @@ -54,162 +59,165 @@ */ public class JvmThreadsMetrics { - private static final String UNKNOWN = "UNKNOWN"; - private static final String JVM_THREADS_STATE = "jvm_threads_state"; - private static final String JVM_THREADS_CURRENT = "jvm_threads_current"; - private static final String JVM_THREADS_DAEMON = "jvm_threads_daemon"; - private static final String JVM_THREADS_PEAK = "jvm_threads_peak"; - private static final String JVM_THREADS_STARTED_TOTAL = "jvm_threads_started_total"; - private static final String JVM_THREADS_DEADLOCKED = "jvm_threads_deadlocked"; - private static final String JVM_THREADS_DEADLOCKED_MONITOR = "jvm_threads_deadlocked_monitor"; + private static final String UNKNOWN = "UNKNOWN"; + private static final String JVM_THREADS_STATE = "jvm_threads_state"; + private static final String JVM_THREADS_CURRENT = "jvm_threads_current"; + private static final String JVM_THREADS_DAEMON = "jvm_threads_daemon"; + private static final String JVM_THREADS_PEAK = "jvm_threads_peak"; + private static final String JVM_THREADS_STARTED_TOTAL = "jvm_threads_started_total"; + private static final String JVM_THREADS_DEADLOCKED = "jvm_threads_deadlocked"; + private static final String JVM_THREADS_DEADLOCKED_MONITOR = "jvm_threads_deadlocked_monitor"; + + private final PrometheusProperties config; + private final ThreadMXBean threadBean; + private final boolean isNativeImage; + + private JvmThreadsMetrics( + boolean isNativeImage, ThreadMXBean threadBean, PrometheusProperties config) { + this.config = config; + this.threadBean = threadBean; + this.isNativeImage = isNativeImage; + } + + private void register(PrometheusRegistry registry) { + + GaugeWithCallback.builder(config) + .name(JVM_THREADS_CURRENT) + .help("Current thread count of a JVM") + .callback(callback -> callback.call(threadBean.getThreadCount())) + .register(registry); + + GaugeWithCallback.builder(config) + .name(JVM_THREADS_DAEMON) + .help("Daemon thread count of a JVM") + .callback(callback -> callback.call(threadBean.getDaemonThreadCount())) + .register(registry); + + GaugeWithCallback.builder(config) + .name(JVM_THREADS_PEAK) + .help("Peak thread count of a JVM") + .callback(callback -> callback.call(threadBean.getPeakThreadCount())) + .register(registry); + + CounterWithCallback.builder(config) + .name(JVM_THREADS_STARTED_TOTAL) + .help("Started thread count of a JVM") + .callback(callback -> callback.call(threadBean.getTotalStartedThreadCount())) + .register(registry); + + if (!isNativeImage) { + GaugeWithCallback.builder(config) + .name(JVM_THREADS_DEADLOCKED) + .help( + "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers") + .callback( + callback -> callback.call(nullSafeArrayLength(threadBean.findDeadlockedThreads()))) + .register(registry); + + GaugeWithCallback.builder(config) + .name(JVM_THREADS_DEADLOCKED_MONITOR) + .help("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors") + .callback( + callback -> + callback.call(nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads()))) + .register(registry); + + GaugeWithCallback.builder(config) + .name(JVM_THREADS_STATE) + .help("Current count of threads by state") + .labelNames("state") + .callback( + callback -> { + MapthreadStateCounts = getThreadStateCountMap(threadBean); + for (Map.Entry entry : threadStateCounts.entrySet()) { + callback.call(entry.getValue(), entry.getKey()); + } + }) + .register(registry); + } + } + + private Map getThreadStateCountMap(ThreadMXBean threadBean) { + long[] threadIds = threadBean.getAllThreadIds(); - private final PrometheusProperties config; - private final ThreadMXBean threadBean; - private final boolean isNativeImage; + // Code to remove any thread id values <= 0 + int writePos = 0; + for (int i = 0; i < threadIds.length; i++) { + if (threadIds[i] > 0) { + threadIds[writePos++] = threadIds[i]; + } + } + + int numberOfInvalidThreadIds = threadIds.length - writePos; + threadIds = Arrays.copyOf(threadIds, writePos); - private JvmThreadsMetrics(boolean isNativeImage, ThreadMXBean threadBean, PrometheusProperties config) { - this.config = config; - this.threadBean = threadBean; - this.isNativeImage = isNativeImage; + // Get thread information without computing any stack traces + ThreadInfo[] allThreads = threadBean.getThreadInfo(threadIds, 0); + + // Initialize the map with all thread states + HashMap threadCounts = new HashMap<>(); + for (Thread.State state : Thread.State.values()) { + threadCounts.put(state.name(), 0); } - private void register(PrometheusRegistry registry) { - - GaugeWithCallback.builder(config) - .name(JVM_THREADS_CURRENT) - .help("Current thread count of a JVM") - .callback(callback -> callback.call(threadBean.getThreadCount())) - .register(registry); - - GaugeWithCallback.builder(config) - .name(JVM_THREADS_DAEMON) - .help("Daemon thread count of a JVM") - .callback(callback -> callback.call(threadBean.getDaemonThreadCount())) - .register(registry); - - GaugeWithCallback.builder(config) - .name(JVM_THREADS_PEAK) - .help("Peak thread count of a JVM") - .callback(callback -> callback.call(threadBean.getPeakThreadCount())) - .register(registry); - - CounterWithCallback.builder(config) - .name(JVM_THREADS_STARTED_TOTAL) - .help("Started thread count of a JVM") - .callback(callback -> callback.call(threadBean.getTotalStartedThreadCount())) - .register(registry); - - if (!isNativeImage) { - GaugeWithCallback.builder(config) - .name(JVM_THREADS_DEADLOCKED) - .help("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers") - .callback(callback -> callback.call(nullSafeArrayLength(threadBean.findDeadlockedThreads()))) - .register(registry); - - GaugeWithCallback.builder(config) - .name(JVM_THREADS_DEADLOCKED_MONITOR) - .help("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors") - .callback(callback -> callback.call(nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads()))) - .register(registry); - - - GaugeWithCallback.builder(config) - .name(JVM_THREADS_STATE) - .help("Current count of threads by state") - .labelNames("state") - .callback(callback -> { - Map threadStateCounts = getThreadStateCountMap(threadBean); - for (Map.Entry entry : threadStateCounts.entrySet()) { - callback.call(entry.getValue(), entry.getKey()); - } - }) - .register(registry); - } + // Collect the actual thread counts + for (ThreadInfo curThread : allThreads) { + if (curThread != null) { + Thread.State threadState = curThread.getThreadState(); + threadCounts.put(threadState.name(), threadCounts.get(threadState.name()) + 1); + } } - private Map getThreadStateCountMap(ThreadMXBean threadBean) { - long[] threadIds = threadBean.getAllThreadIds(); - - // Code to remove any thread id values <= 0 - int writePos = 0; - for (int i = 0; i < threadIds.length; i++) { - if (threadIds[i] > 0) { - threadIds[writePos++] = threadIds[i]; - } - } - - int numberOfInvalidThreadIds = threadIds.length - writePos; - threadIds = Arrays.copyOf(threadIds, writePos); - - // Get thread information without computing any stack traces - ThreadInfo[] allThreads = threadBean.getThreadInfo(threadIds, 0); - - // Initialize the map with all thread states - HashMap threadCounts = new HashMap<>(); - for (Thread.State state : Thread.State.values()) { - threadCounts.put(state.name(), 0); - } - - // Collect the actual thread counts - for (ThreadInfo curThread : allThreads) { - if (curThread != null) { - Thread.State threadState = curThread.getThreadState(); - threadCounts.put(threadState.name(), threadCounts.get(threadState.name()) + 1); - } - } - - // Add the thread count for invalid thread ids - threadCounts.put(UNKNOWN, numberOfInvalidThreadIds); - - return threadCounts; + // Add the thread count for invalid thread ids + threadCounts.put(UNKNOWN, numberOfInvalidThreadIds); + + return threadCounts; + } + + private double nullSafeArrayLength(long[] array) { + return null == array ? 0 : array.length; + } + + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private Boolean isNativeImage; + private ThreadMXBean threadBean; + + private Builder(PrometheusProperties config) { + this.config = config; } - private double nullSafeArrayLength(long[] array) { - return null == array ? 0 : array.length; + /** Package private. For testing only. */ + Builder threadBean(ThreadMXBean threadBean) { + this.threadBean = threadBean; + return this; } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + /** Package private. For testing only. */ + Builder isNativeImage(boolean isNativeImage) { + this.isNativeImage = isNativeImage; + return this; } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + public void register() { + register(PrometheusRegistry.defaultRegistry); } - public static class Builder { - - private final PrometheusProperties config; - private Boolean isNativeImage; - private ThreadMXBean threadBean; - - private Builder(PrometheusProperties config) { - this.config = config; - } - - /** - * Package private. For testing only. - */ - Builder threadBean(ThreadMXBean threadBean) { - this.threadBean = threadBean; - return this; - } - - /** - * Package private. For testing only. - */ - Builder isNativeImage(boolean isNativeImage) { - this.isNativeImage = isNativeImage; - return this; - } - - public void register() { - register(PrometheusRegistry.defaultRegistry); - } - - public void register(PrometheusRegistry registry) { - ThreadMXBean threadBean = this.threadBean != null ? this.threadBean : ManagementFactory.getThreadMXBean(); - boolean isNativeImage = this.isNativeImage != null ? this.isNativeImage : NativeImageChecker.isGraalVmNativeImage; - new JvmThreadsMetrics(isNativeImage, threadBean, config).register(registry); - } + public void register(PrometheusRegistry registry) { + ThreadMXBean threadBean = + this.threadBean != null ? this.threadBean : ManagementFactory.getThreadMXBean(); + boolean isNativeImage = + this.isNativeImage != null ? this.isNativeImage : NativeImageChecker.isGraalVmNativeImage; + new JvmThreadsMetrics(isNativeImage, threadBean, config).register(registry); } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java index 4eb476216..bd7fb14b1 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java @@ -5,7 +5,6 @@ import io.prometheus.metrics.core.metrics.GaugeWithCallback; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.Unit; - import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -18,23 +17,31 @@ /** * Process metrics. - * - * These metrics are defined in the process metrics - * section of the Prometheus client library documentation, and they are implemented across client libraries in multiple programming languages. - *
- * Technically, some of them are OS-level metrics and not JVM-level metrics. However, I'm still putting them - * in the {@code prometheus-metrics-instrumentation-jvm} module, because first it seems overkill to create a separate - * Maven module just for the {@link ProcessMetrics} class, and seconds some of these metrics are coming from the JVM via JMX anyway. - *
- * The {@link ProcessMetrics} are registered as part of the {@link JvmMetrics} like this: + * + *
These metrics are defined in the process + * metrics section of the Prometheus client library documentation, and they are implemented + * across client libraries in multiple programming languages. + * + *
Technically, some of them are OS-level metrics and not JVM-level metrics. However, I'm still + * putting them in the {@code prometheus-metrics-instrumentation-jvm} module, because first it seems + * overkill to create a separate Maven module just for the {@link ProcessMetrics} class, and seconds + * some of these metrics are coming from the JVM via JMX anyway. + * + *
The {@link ProcessMetrics} are registered as part of the {@link JvmMetrics} like this: + * *
{@code - * JvmMetrics.builder().register(); + * JvmMetrics.builder().register(); * }+ * * However, if you want only the {@link ProcessMetrics} you can also register them directly: + * *{@code - * ProcessMetrics.builder().register(); + * ProcessMetrics.builder().register(); * }+ * * Example metrics being exported: + * ** # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. * # TYPE process_cpu_seconds_total counter @@ -58,228 +65,237 @@ */ public class ProcessMetrics { - private static final String PROCESS_CPU_SECONDS_TOTAL = "process_cpu_seconds_total"; - private static final String PROCESS_START_TIME_SECONDS = "process_start_time_seconds"; - private static final String PROCESS_OPEN_FDS = "process_open_fds"; - private static final String PROCESS_MAX_FDS = "process_max_fds"; - private static final String PROCESS_VIRTUAL_MEMORY_BYTES = "process_virtual_memory_bytes"; - private static final String PROCESS_RESIDENT_MEMORY_BYTES = "process_resident_memory_bytes"; + private static final String PROCESS_CPU_SECONDS_TOTAL = "process_cpu_seconds_total"; + private static final String PROCESS_START_TIME_SECONDS = "process_start_time_seconds"; + private static final String PROCESS_OPEN_FDS = "process_open_fds"; + private static final String PROCESS_MAX_FDS = "process_max_fds"; + private static final String PROCESS_VIRTUAL_MEMORY_BYTES = "process_virtual_memory_bytes"; + private static final String PROCESS_RESIDENT_MEMORY_BYTES = "process_resident_memory_bytes"; - static final File PROC_SELF_STATUS = new File("/proc/self/status"); + static final File PROC_SELF_STATUS = new File("/proc/self/status"); - private final PrometheusProperties config; - private final OperatingSystemMXBean osBean; - private final RuntimeMXBean runtimeBean; - private final Grepper grepper; - private final boolean linux; + private final PrometheusProperties config; + private final OperatingSystemMXBean osBean; + private final RuntimeMXBean runtimeBean; + private final Grepper grepper; + private final boolean linux; - private ProcessMetrics(OperatingSystemMXBean osBean, RuntimeMXBean runtimeBean, Grepper grepper, PrometheusProperties config) { - this.osBean = osBean; - this.runtimeBean = runtimeBean; - this.grepper = grepper; - this.config = config; - this.linux = PROC_SELF_STATUS.canRead(); - } + private ProcessMetrics( + OperatingSystemMXBean osBean, + RuntimeMXBean runtimeBean, + Grepper grepper, + PrometheusProperties config) { + this.osBean = osBean; + this.runtimeBean = runtimeBean; + this.grepper = grepper; + this.config = config; + this.linux = PROC_SELF_STATUS.canRead(); + } - private void register(PrometheusRegistry registry) { + private void register(PrometheusRegistry registry) { - CounterWithCallback.builder(config) - .name(PROCESS_CPU_SECONDS_TOTAL) - .help("Total user and system CPU time spent in seconds.") - .unit(Unit.SECONDS) - .callback(callback -> { - try { - // There exist at least 2 similar but unrelated UnixOperatingSystemMXBean interfaces, in - // com.sun.management and com.ibm.lang.management. Hence use reflection and recursively go - // through implemented interfaces until the method can be made accessible and invoked. - Long processCpuTime = callLongGetter("getProcessCpuTime", osBean); - if (processCpuTime != null) { - callback.call(Unit.nanosToSeconds(processCpuTime)); - } - } catch (Exception ignored) { - } - }) - .register(registry); + CounterWithCallback.builder(config) + .name(PROCESS_CPU_SECONDS_TOTAL) + .help("Total user and system CPU time spent in seconds.") + .unit(Unit.SECONDS) + .callback( + callback -> { + try { + // There exist at least 2 similar but unrelated UnixOperatingSystemMXBean + // interfaces, in + // com.sun.management and com.ibm.lang.management. Hence use reflection and + // recursively go + // through implemented interfaces until the method can be made accessible and + // invoked. + Long processCpuTime = callLongGetter("getProcessCpuTime", osBean); + if (processCpuTime != null) { + callback.call(Unit.nanosToSeconds(processCpuTime)); + } + } catch (Exception ignored) { + } + }) + .register(registry); - GaugeWithCallback.builder(config) - .name(PROCESS_START_TIME_SECONDS) - .help("Start time of the process since unix epoch in seconds.") - .unit(Unit.SECONDS) - .callback(callback -> callback.call(Unit.millisToSeconds(runtimeBean.getStartTime()))) - .register(registry); + GaugeWithCallback.builder(config) + .name(PROCESS_START_TIME_SECONDS) + .help("Start time of the process since unix epoch in seconds.") + .unit(Unit.SECONDS) + .callback(callback -> callback.call(Unit.millisToSeconds(runtimeBean.getStartTime()))) + .register(registry); - GaugeWithCallback.builder(config) - .name(PROCESS_OPEN_FDS) - .help("Number of open file descriptors.") - .callback(callback -> { - try { - Long openFds = callLongGetter("getOpenFileDescriptorCount", osBean); - if (openFds != null) { - callback.call(openFds); - } - } catch (Exception ignored) { - } - }) - .register(registry); + GaugeWithCallback.builder(config) + .name(PROCESS_OPEN_FDS) + .help("Number of open file descriptors.") + .callback( + callback -> { + try { + Long openFds = callLongGetter("getOpenFileDescriptorCount", osBean); + if (openFds != null) { + callback.call(openFds); + } + } catch (Exception ignored) { + } + }) + .register(registry); - GaugeWithCallback.builder(config) - .name(PROCESS_MAX_FDS) - .help("Maximum number of open file descriptors.") - .callback(callback -> { - try { - Long maxFds = callLongGetter("getMaxFileDescriptorCount", osBean); - if (maxFds != null) { - callback.call(maxFds); - } - } catch (Exception ignored) { - } - }) - .register(registry); + GaugeWithCallback.builder(config) + .name(PROCESS_MAX_FDS) + .help("Maximum number of open file descriptors.") + .callback( + callback -> { + try { + Long maxFds = callLongGetter("getMaxFileDescriptorCount", osBean); + if (maxFds != null) { + callback.call(maxFds); + } + } catch (Exception ignored) { + } + }) + .register(registry); - if (linux) { + if (linux) { - GaugeWithCallback.builder(config) - .name(PROCESS_VIRTUAL_MEMORY_BYTES) - .help("Virtual memory size in bytes.") - .unit(Unit.BYTES) - .callback(callback -> { - try { - String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmSize:"); - callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1]))); - } catch (Exception ignored) { - } - }) - .register(registry); + GaugeWithCallback.builder(config) + .name(PROCESS_VIRTUAL_MEMORY_BYTES) + .help("Virtual memory size in bytes.") + .unit(Unit.BYTES) + .callback( + callback -> { + try { + String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmSize:"); + callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1]))); + } catch (Exception ignored) { + } + }) + .register(registry); - GaugeWithCallback.builder(config) - .name(PROCESS_RESIDENT_MEMORY_BYTES) - .help("Resident memory size in bytes.") - .unit(Unit.BYTES) - .callback(callback -> { - try { - String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmRSS:"); - callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1]))); - } catch (Exception ignored) { - } - }) - .register(registry); - } + GaugeWithCallback.builder(config) + .name(PROCESS_RESIDENT_MEMORY_BYTES) + .help("Resident memory size in bytes.") + .unit(Unit.BYTES) + .callback( + callback -> { + try { + String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmRSS:"); + callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1]))); + } catch (Exception ignored) { + } + }) + .register(registry); } + } + + private Long callLongGetter(String getterName, Object obj) + throws NoSuchMethodException, InvocationTargetException { + return callLongGetter(obj.getClass().getMethod(getterName), obj); + } - private Long callLongGetter(String getterName, Object obj) throws NoSuchMethodException, InvocationTargetException { - return callLongGetter(obj.getClass().getMethod(getterName), obj); + /** + * Attempts to call a method either directly or via one of the implemented interfaces. + * + *A Method object refers to a specific method declared in a specific class. The first + * invocation might happen with method == SomeConcreteClass.publicLongGetter() and will fail if + * SomeConcreteClass is not public. We then recurse over all interfaces implemented by + * SomeConcreteClass (or extended by those interfaces and so on) until we eventually invoke + * callMethod() with method == SomePublicInterface.publicLongGetter(), which will then succeed. + * + *
There is a built-in assumption that the method will never return null (or, equivalently, + * that it returns the primitive data type, i.e. {@code long} rather than {@code Long}). If this + * assumption doesn't hold, the method might be called repeatedly and the returned value will be + * the one produced by the last call. + */ + private Long callLongGetter(Method method, Object obj) throws InvocationTargetException { + try { + return (Long) method.invoke(obj); + } catch (IllegalAccessException e) { + // Expected, the declaring class or interface might not be public. } - /** - * Attempts to call a method either directly or via one of the implemented interfaces. - *
- * A Method object refers to a specific method declared in a specific class. The first invocation - * might happen with method == SomeConcreteClass.publicLongGetter() and will fail if - * SomeConcreteClass is not public. We then recurse over all interfaces implemented by - * SomeConcreteClass (or extended by those interfaces and so on) until we eventually invoke - * callMethod() with method == SomePublicInterface.publicLongGetter(), which will then succeed. - *
- * There is a built-in assumption that the method will never return null (or, equivalently, that - * it returns the primitive data type, i.e. {@code long} rather than {@code Long}). If this - * assumption doesn't hold, the method might be called repeatedly and the returned value will be - * the one produced by the last call. - */ - private Long callLongGetter(Method method, Object obj) throws InvocationTargetException { - try { - return (Long) method.invoke(obj); - } catch (IllegalAccessException e) { - // Expected, the declaring class or interface might not be public. + // Iterate over all implemented/extended interfaces and attempt invoking the method with the + // same name and parameters on each. + for (Class> clazz : method.getDeclaringClass().getInterfaces()) { + try { + Method interfaceMethod = clazz.getMethod(method.getName(), method.getParameterTypes()); + Long result = callLongGetter(interfaceMethod, obj); + if (result != null) { + return result; } - - // Iterate over all implemented/extended interfaces and attempt invoking the method with the - // same name and parameters on each. - for (Class> clazz : method.getDeclaringClass().getInterfaces()) { - try { - Method interfaceMethod = clazz.getMethod(method.getName(), method.getParameterTypes()); - Long result = callLongGetter(interfaceMethod, obj); - if (result != null) { - return result; - } - } catch (NoSuchMethodException e) { - // Expected, class might implement multiple, unrelated interfaces. - } - } - return null; + } catch (NoSuchMethodException e) { + // Expected, class might implement multiple, unrelated interfaces. + } } + return null; + } - interface Grepper { - String lineStartingWith(File file, String prefix) throws IOException; - } + interface Grepper { + String lineStartingWith(File file, String prefix) throws IOException; + } - private static class FileGrepper implements Grepper { + private static class FileGrepper implements Grepper { - @Override - public String lineStartingWith(File file, String prefix) throws IOException { - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line = reader.readLine(); - while (line != null) { - if (line.startsWith(prefix)) { - return line; - } - line = reader.readLine(); - } - } - return null; + @Override + public String lineStartingWith(File file, String prefix) throws IOException { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line = reader.readLine(); + while (line != null) { + if (line.startsWith(prefix)) { + return line; + } + line = reader.readLine(); } + } + return null; } + } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); - } + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); - } + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } - public static class Builder { + public static class Builder { - private final PrometheusProperties config; - private OperatingSystemMXBean osBean; - private RuntimeMXBean runtimeBean; - private Grepper grepper; + private final PrometheusProperties config; + private OperatingSystemMXBean osBean; + private RuntimeMXBean runtimeBean; + private Grepper grepper; - private Builder(PrometheusProperties config) { - this.config = config; - } + private Builder(PrometheusProperties config) { + this.config = config; + } - /** - * Package private. For testing only. - */ - Builder osBean(OperatingSystemMXBean osBean) { - this.osBean = osBean; - return this; - } + /** Package private. For testing only. */ + Builder osBean(OperatingSystemMXBean osBean) { + this.osBean = osBean; + return this; + } - /** - * Package private. For testing only. - */ - Builder runtimeBean(RuntimeMXBean runtimeBean) { - this.runtimeBean = runtimeBean; - return this; - } + /** Package private. For testing only. */ + Builder runtimeBean(RuntimeMXBean runtimeBean) { + this.runtimeBean = runtimeBean; + return this; + } - /** - * Package private. For testing only. - */ - Builder grepper(Grepper grepper) { - this.grepper = grepper; - return this; - } + /** Package private. For testing only. */ + Builder grepper(Grepper grepper) { + this.grepper = grepper; + return this; + } - public void register() { - register(PrometheusRegistry.defaultRegistry); - } + public void register() { + register(PrometheusRegistry.defaultRegistry); + } - public void register(PrometheusRegistry registry) { - OperatingSystemMXBean osBean = this.osBean != null ? this.osBean : ManagementFactory.getOperatingSystemMXBean(); - RuntimeMXBean runtimeMXBean = this.runtimeBean != null ? this.runtimeBean : ManagementFactory.getRuntimeMXBean(); - Grepper grepper = this.grepper != null ? this.grepper : new FileGrepper(); - new ProcessMetrics(osBean, runtimeMXBean, grepper, config).register(registry); - } + public void register(PrometheusRegistry registry) { + OperatingSystemMXBean osBean = + this.osBean != null ? this.osBean : ManagementFactory.getOperatingSystemMXBean(); + RuntimeMXBean runtimeMXBean = + this.runtimeBean != null ? this.runtimeBean : ManagementFactory.getRuntimeMXBean(); + Grepper grepper = this.grepper != null ? this.grepper : new FileGrepper(); + new ProcessMetrics(osBean, runtimeMXBean, grepper, config).register(registry); } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java index 2ea3174eb..533ce103f 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java @@ -1,82 +1,80 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; +import java.lang.management.BufferPoolMXBean; +import java.util.Arrays; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import java.io.IOException; -import java.lang.management.BufferPoolMXBean; -import java.util.Arrays; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - public class JvmBufferPoolMetricsTest { - private final BufferPoolMXBean directBuffer = Mockito.mock(BufferPoolMXBean.class); - private final BufferPoolMXBean mappedBuffer = Mockito.mock(BufferPoolMXBean.class); + private final BufferPoolMXBean directBuffer = Mockito.mock(BufferPoolMXBean.class); + private final BufferPoolMXBean mappedBuffer = Mockito.mock(BufferPoolMXBean.class); - @Before - public void setUp() { - when(directBuffer.getName()).thenReturn("direct"); - when(directBuffer.getCount()).thenReturn(2L); - when(directBuffer.getMemoryUsed()).thenReturn(1234L); - when(directBuffer.getTotalCapacity()).thenReturn(3456L); - when(mappedBuffer.getName()).thenReturn("mapped"); - when(mappedBuffer.getCount()).thenReturn(3L); - when(mappedBuffer.getMemoryUsed()).thenReturn(2345L); - when(mappedBuffer.getTotalCapacity()).thenReturn(4567L); - } + @Before + public void setUp() { + when(directBuffer.getName()).thenReturn("direct"); + when(directBuffer.getCount()).thenReturn(2L); + when(directBuffer.getMemoryUsed()).thenReturn(1234L); + when(directBuffer.getTotalCapacity()).thenReturn(3456L); + when(mappedBuffer.getName()).thenReturn("mapped"); + when(mappedBuffer.getCount()).thenReturn(3L); + when(mappedBuffer.getMemoryUsed()).thenReturn(2345L); + when(mappedBuffer.getTotalCapacity()).thenReturn(4567L); + } - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmBufferPoolMetrics.builder() - .bufferPoolBeans(Arrays.asList(mappedBuffer, directBuffer)) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmBufferPoolMetrics.builder() + .bufferPoolBeans(Arrays.asList(mappedBuffer, directBuffer)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - String expected = - "# TYPE jvm_buffer_pool_capacity_bytes gauge\n" + - "# UNIT jvm_buffer_pool_capacity_bytes bytes\n" + - "# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.\n" + - "jvm_buffer_pool_capacity_bytes{pool=\"direct\"} 3456.0\n" + - "jvm_buffer_pool_capacity_bytes{pool=\"mapped\"} 4567.0\n" + - "# TYPE jvm_buffer_pool_used_buffers gauge\n" + - "# HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool.\n" + - "jvm_buffer_pool_used_buffers{pool=\"direct\"} 2.0\n" + - "jvm_buffer_pool_used_buffers{pool=\"mapped\"} 3.0\n" + - "# TYPE jvm_buffer_pool_used_bytes gauge\n" + - "# UNIT jvm_buffer_pool_used_bytes bytes\n" + - "# HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool.\n" + - "jvm_buffer_pool_used_bytes{pool=\"direct\"} 1234.0\n" + - "jvm_buffer_pool_used_bytes{pool=\"mapped\"} 2345.0\n" + - "# EOF\n"; + String expected = + "# TYPE jvm_buffer_pool_capacity_bytes gauge\n" + + "# UNIT jvm_buffer_pool_capacity_bytes bytes\n" + + "# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.\n" + + "jvm_buffer_pool_capacity_bytes{pool=\"direct\"} 3456.0\n" + + "jvm_buffer_pool_capacity_bytes{pool=\"mapped\"} 4567.0\n" + + "# TYPE jvm_buffer_pool_used_buffers gauge\n" + + "# HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool.\n" + + "jvm_buffer_pool_used_buffers{pool=\"direct\"} 2.0\n" + + "jvm_buffer_pool_used_buffers{pool=\"mapped\"} 3.0\n" + + "# TYPE jvm_buffer_pool_used_bytes gauge\n" + + "# UNIT jvm_buffer_pool_used_bytes bytes\n" + + "# HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool.\n" + + "jvm_buffer_pool_used_bytes{pool=\"direct\"} 1234.0\n" + + "jvm_buffer_pool_used_bytes{pool=\"mapped\"} 2345.0\n" + + "# EOF\n"; - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_buffer_pool_used_bytes") - .build(); + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_buffer_pool_used_bytes").build(); - PrometheusRegistry registry = new PrometheusRegistry(); - JvmBufferPoolMetrics.builder() - .bufferPoolBeans(Arrays.asList(directBuffer, mappedBuffer)) - .register(registry); - registry.scrape(filter); + PrometheusRegistry registry = new PrometheusRegistry(); + JvmBufferPoolMetrics.builder() + .bufferPoolBeans(Arrays.asList(directBuffer, mappedBuffer)) + .register(registry); + registry.scrape(filter); - verify(directBuffer, times(0)).getMemoryUsed(); - verify(mappedBuffer, times(0)).getMemoryUsed(); - verify(directBuffer, times(1)).getTotalCapacity(); - verify(mappedBuffer, times(1)).getTotalCapacity(); - } + verify(directBuffer, times(0)).getMemoryUsed(); + verify(mappedBuffer, times(0)).getMemoryUsed(); + verify(directBuffer, times(1)).getTotalCapacity(); + verify(mappedBuffer, times(1)).getTotalCapacity(); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java index 2a3f37306..26ab36220 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java @@ -1,68 +1,62 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; +import java.lang.management.ClassLoadingMXBean; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import java.io.IOException; -import java.lang.management.ClassLoadingMXBean; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - public class JvmClassLoadingMetricsTest { - private final ClassLoadingMXBean mockClassLoadingBean = Mockito.mock(ClassLoadingMXBean.class); - - @Before - public void setUp() { - when(mockClassLoadingBean.getLoadedClassCount()).thenReturn(1000); - when(mockClassLoadingBean.getTotalLoadedClassCount()).thenReturn(2000L); - when(mockClassLoadingBean.getUnloadedClassCount()).thenReturn(500L); - } - - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmClassLoadingMetrics.builder() - .classLoadingBean(mockClassLoadingBean) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); - - String expected = - "# TYPE jvm_classes_currently_loaded gauge\n" + - "# HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM\n" + - "jvm_classes_currently_loaded 1000.0\n" + - "# TYPE jvm_classes_loaded counter\n" + - "# HELP jvm_classes_loaded The total number of classes that have been loaded since the JVM has started execution\n" + - "jvm_classes_loaded_total 2000.0\n" + - "# TYPE jvm_classes_unloaded counter\n" + - "# HELP jvm_classes_unloaded The total number of classes that have been unloaded since the JVM has started execution\n" + - "jvm_classes_unloaded_total 500.0\n" + - "# EOF\n"; - - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } - - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_classes_currently_loaded") - .build(); - - PrometheusRegistry registry = new PrometheusRegistry(); - JvmClassLoadingMetrics.builder() - .classLoadingBean(mockClassLoadingBean) - .register(registry); - registry.scrape(filter); - - verify(mockClassLoadingBean, times(0)).getLoadedClassCount(); - verify(mockClassLoadingBean, times(1)).getTotalLoadedClassCount(); - } + private final ClassLoadingMXBean mockClassLoadingBean = Mockito.mock(ClassLoadingMXBean.class); + + @Before + public void setUp() { + when(mockClassLoadingBean.getLoadedClassCount()).thenReturn(1000); + when(mockClassLoadingBean.getTotalLoadedClassCount()).thenReturn(2000L); + when(mockClassLoadingBean.getUnloadedClassCount()).thenReturn(500L); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmClassLoadingMetrics.builder().classLoadingBean(mockClassLoadingBean).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = + "# TYPE jvm_classes_currently_loaded gauge\n" + + "# HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM\n" + + "jvm_classes_currently_loaded 1000.0\n" + + "# TYPE jvm_classes_loaded counter\n" + + "# HELP jvm_classes_loaded The total number of classes that have been loaded since the JVM has started execution\n" + + "jvm_classes_loaded_total 2000.0\n" + + "# TYPE jvm_classes_unloaded counter\n" + + "# HELP jvm_classes_unloaded The total number of classes that have been unloaded since the JVM has started execution\n" + + "jvm_classes_unloaded_total 500.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_classes_currently_loaded").build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmClassLoadingMetrics.builder().classLoadingBean(mockClassLoadingBean).register(registry); + registry.scrape(filter); + + verify(mockClassLoadingBean, times(0)).getLoadedClassCount(); + verify(mockClassLoadingBean, times(1)).getTotalLoadedClassCount(); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java index 37b0dfc8e..91f9003fe 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java @@ -1,62 +1,58 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.internal.verification.VerificationModeFactory.times; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; +import java.lang.management.CompilationMXBean; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import java.io.IOException; -import java.lang.management.CompilationMXBean; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.internal.verification.VerificationModeFactory.times; - public class JvmCompilationMetricsTest { - private final CompilationMXBean mockCompilationBean = Mockito.mock(CompilationMXBean.class); - - @Before - public void setUp() { - when(mockCompilationBean.getTotalCompilationTime()).thenReturn(10000L); - when(mockCompilationBean.isCompilationTimeMonitoringSupported()).thenReturn(true); - } - - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmCompilationMetrics.builder() - .compilationBean(mockCompilationBean) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); - - String expected = - "# TYPE jvm_compilation_time_seconds counter\n" + - "# UNIT jvm_compilation_time_seconds seconds\n" + - "# HELP jvm_compilation_time_seconds The total time in seconds taken for HotSpot class compilation\n" + - "jvm_compilation_time_seconds_total 10.0\n" + - "# EOF\n"; - - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } - - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_compilation_time_seconds_total") - .build(); - - PrometheusRegistry registry = new PrometheusRegistry(); - JvmCompilationMetrics.builder() - .compilationBean(mockCompilationBean) - .register(registry); - MetricSnapshots snapshots = registry.scrape(filter); - - verify(mockCompilationBean, times(0)).getTotalCompilationTime(); - Assert.assertEquals(0, snapshots.size()); - } + private final CompilationMXBean mockCompilationBean = Mockito.mock(CompilationMXBean.class); + + @Before + public void setUp() { + when(mockCompilationBean.getTotalCompilationTime()).thenReturn(10000L); + when(mockCompilationBean.isCompilationTimeMonitoringSupported()).thenReturn(true); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmCompilationMetrics.builder().compilationBean(mockCompilationBean).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = + "# TYPE jvm_compilation_time_seconds counter\n" + + "# UNIT jvm_compilation_time_seconds seconds\n" + + "# HELP jvm_compilation_time_seconds The total time in seconds taken for HotSpot class compilation\n" + + "jvm_compilation_time_seconds_total 10.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder() + .nameMustNotBeEqualTo("jvm_compilation_time_seconds_total") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmCompilationMetrics.builder().compilationBean(mockCompilationBean).register(registry); + MetricSnapshots snapshots = registry.scrape(filter); + + verify(mockCompilationBean, times(0)).getTotalCompilationTime(); + Assert.assertEquals(0, snapshots.size()); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java index d7cc6ec84..48c79e8e8 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java @@ -1,74 +1,71 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import java.io.IOException; import java.lang.management.GarbageCollectorMXBean; import java.util.Arrays; import java.util.concurrent.TimeUnit; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; public class JvmGarbageCollectorMetricsTest { - private final GarbageCollectorMXBean mockGcBean1 = Mockito.mock(GarbageCollectorMXBean.class); - private final GarbageCollectorMXBean mockGcBean2 = Mockito.mock(GarbageCollectorMXBean.class); + private final GarbageCollectorMXBean mockGcBean1 = Mockito.mock(GarbageCollectorMXBean.class); + private final GarbageCollectorMXBean mockGcBean2 = Mockito.mock(GarbageCollectorMXBean.class); - @Before - public void setUp() { - when(mockGcBean1.getName()).thenReturn("MyGC1"); - when(mockGcBean1.getCollectionCount()).thenReturn(100L); - when(mockGcBean1.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(10)); - when(mockGcBean2.getName()).thenReturn("MyGC2"); - when(mockGcBean2.getCollectionCount()).thenReturn(200L); - when(mockGcBean2.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(20)); - } + @Before + public void setUp() { + when(mockGcBean1.getName()).thenReturn("MyGC1"); + when(mockGcBean1.getCollectionCount()).thenReturn(100L); + when(mockGcBean1.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(10)); + when(mockGcBean2.getName()).thenReturn("MyGC2"); + when(mockGcBean2.getCollectionCount()).thenReturn(200L); + when(mockGcBean2.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(20)); + } - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmGarbageCollectorMetrics.builder() - .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmGarbageCollectorMetrics.builder() + .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - String expected = - "# TYPE jvm_gc_collection_seconds summary\n" + - "# UNIT jvm_gc_collection_seconds seconds\n" + - "# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.\n" + - "jvm_gc_collection_seconds_count{gc=\"MyGC1\"} 100\n" + - "jvm_gc_collection_seconds_sum{gc=\"MyGC1\"} 10.0\n" + - "jvm_gc_collection_seconds_count{gc=\"MyGC2\"} 200\n" + - "jvm_gc_collection_seconds_sum{gc=\"MyGC2\"} 20.0\n" + - "# EOF\n"; + String expected = + "# TYPE jvm_gc_collection_seconds summary\n" + + "# UNIT jvm_gc_collection_seconds seconds\n" + + "# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.\n" + + "jvm_gc_collection_seconds_count{gc=\"MyGC1\"} 100\n" + + "jvm_gc_collection_seconds_sum{gc=\"MyGC1\"} 10.0\n" + + "jvm_gc_collection_seconds_count{gc=\"MyGC2\"} 200\n" + + "jvm_gc_collection_seconds_sum{gc=\"MyGC2\"} 20.0\n" + + "# EOF\n"; - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_gc_collection_seconds") - .build(); + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_gc_collection_seconds").build(); - PrometheusRegistry registry = new PrometheusRegistry(); - JvmGarbageCollectorMetrics.builder() - .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) - .register(registry); - MetricSnapshots snapshots = registry.scrape(filter); + PrometheusRegistry registry = new PrometheusRegistry(); + JvmGarbageCollectorMetrics.builder() + .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(filter); - verify(mockGcBean1, times(0)).getCollectionTime(); - verify(mockGcBean1, times(0)).getCollectionCount(); - Assert.assertEquals(0, snapshots.size()); - } + verify(mockGcBean1, times(0)).getCollectionTime(); + verify(mockGcBean1, times(0)).getCollectionCount(); + Assert.assertEquals(0, snapshots.size()); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java index c10faab9c..e258117ff 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java @@ -1,177 +1,176 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import java.io.IOException; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryPoolMXBean; import java.lang.management.MemoryUsage; import java.util.Arrays; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; public class JvmMemoryMetricsTest { - private final MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class); - private final MemoryPoolMXBean mockPoolsBeanEdenSpace = Mockito.mock(MemoryPoolMXBean.class); - private final MemoryPoolMXBean mockPoolsBeanOldGen = Mockito.mock(MemoryPoolMXBean.class); - private final MemoryUsage memoryUsageHeap = Mockito.mock(MemoryUsage.class); - private final MemoryUsage memoryUsageNonHeap = Mockito.mock(MemoryUsage.class); - private final MemoryUsage memoryUsagePoolEdenSpace = Mockito.mock(MemoryUsage.class); - private final MemoryUsage memoryUsagePoolOldGen = Mockito.mock(MemoryUsage.class); - private final MemoryUsage memoryUsagePoolCollectionEdenSpace = Mockito.mock(MemoryUsage.class); - private final MemoryUsage memoryUsagePoolCollectionOldGen = Mockito.mock(MemoryUsage.class); - - @Before - public void setUp() { - when(mockMemoryBean.getHeapMemoryUsage()).thenReturn(memoryUsageHeap); - when(mockMemoryBean.getNonHeapMemoryUsage()).thenReturn(memoryUsageNonHeap); - - long val = 1L; - when(mockMemoryBean.getObjectPendingFinalizationCount()).thenReturn((int) val++); - - when(memoryUsageHeap.getUsed()).thenReturn(val++); - when(memoryUsageHeap.getMax()).thenReturn(val++); - when(memoryUsageHeap.getCommitted()).thenReturn(val++); - when(memoryUsageHeap.getInit()).thenReturn(val++); - - when(memoryUsageNonHeap.getUsed()).thenReturn(val++); - when(memoryUsageNonHeap.getMax()).thenReturn(val++); - when(memoryUsageNonHeap.getCommitted()).thenReturn(val++); - when(memoryUsageNonHeap.getInit()).thenReturn(val++); - - when(memoryUsagePoolEdenSpace.getUsed()).thenReturn(val++); - when(memoryUsagePoolEdenSpace.getMax()).thenReturn(val++); - when(memoryUsagePoolEdenSpace.getCommitted()).thenReturn(val++); - when(memoryUsagePoolEdenSpace.getInit()).thenReturn(val++); - - when(memoryUsagePoolOldGen.getUsed()).thenReturn(val++); - when(memoryUsagePoolOldGen.getMax()).thenReturn(val++); - when(memoryUsagePoolOldGen.getCommitted()).thenReturn(val++); - when(memoryUsagePoolOldGen.getInit()).thenReturn(val++); - - when(memoryUsagePoolCollectionEdenSpace.getUsed()).thenReturn(val++); - when(memoryUsagePoolCollectionEdenSpace.getMax()).thenReturn(val++); - when(memoryUsagePoolCollectionEdenSpace.getCommitted()).thenReturn(val++); - when(memoryUsagePoolCollectionEdenSpace.getInit()).thenReturn(val++); - - when(memoryUsagePoolCollectionOldGen.getUsed()).thenReturn(val++); - when(memoryUsagePoolCollectionOldGen.getMax()).thenReturn(val++); - when(memoryUsagePoolCollectionOldGen.getCommitted()).thenReturn(val++); - when(memoryUsagePoolCollectionOldGen.getInit()).thenReturn(val++); - - when(mockPoolsBeanEdenSpace.getName()).thenReturn("PS Eden Space"); - when(mockPoolsBeanEdenSpace.getUsage()).thenReturn(memoryUsagePoolEdenSpace); - when(mockPoolsBeanEdenSpace.getCollectionUsage()).thenReturn(memoryUsagePoolCollectionEdenSpace); - - when(mockPoolsBeanOldGen.getName()).thenReturn("PS Old Gen"); - when(mockPoolsBeanOldGen.getUsage()).thenReturn(memoryUsagePoolOldGen); - when(mockPoolsBeanOldGen.getCollectionUsage()).thenReturn(memoryUsagePoolCollectionOldGen); - } - - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmMemoryMetrics.builder() - .withMemoryBean(mockMemoryBean) - .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); - - String expected = - "# TYPE jvm_memory_committed_bytes gauge\n" + - "# UNIT jvm_memory_committed_bytes bytes\n" + - "# HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.\n" + - "jvm_memory_committed_bytes{area=\"heap\"} 4.0\n" + - "jvm_memory_committed_bytes{area=\"nonheap\"} 8.0\n" + - "# TYPE jvm_memory_init_bytes gauge\n" + - "# UNIT jvm_memory_init_bytes bytes\n" + - "# HELP jvm_memory_init_bytes Initial bytes of a given JVM memory area.\n" + - "jvm_memory_init_bytes{area=\"heap\"} 5.0\n" + - "jvm_memory_init_bytes{area=\"nonheap\"} 9.0\n" + - "# TYPE jvm_memory_max_bytes gauge\n" + - "# UNIT jvm_memory_max_bytes bytes\n" + - "# HELP jvm_memory_max_bytes Max (bytes) of a given JVM memory area.\n" + - "jvm_memory_max_bytes{area=\"heap\"} 3.0\n" + - "jvm_memory_max_bytes{area=\"nonheap\"} 7.0\n" + - "# TYPE jvm_memory_objects_pending_finalization gauge\n" + - "# HELP jvm_memory_objects_pending_finalization The number of objects waiting in the finalizer queue.\n" + - "jvm_memory_objects_pending_finalization 1.0\n" + - "# TYPE jvm_memory_pool_collection_committed_bytes gauge\n" + - "# UNIT jvm_memory_pool_collection_committed_bytes bytes\n" + - "# HELP jvm_memory_pool_collection_committed_bytes Committed after last collection bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_collection_committed_bytes{pool=\"PS Eden Space\"} 20.0\n" + - "jvm_memory_pool_collection_committed_bytes{pool=\"PS Old Gen\"} 24.0\n" + - "# TYPE jvm_memory_pool_collection_init_bytes gauge\n" + - "# UNIT jvm_memory_pool_collection_init_bytes bytes\n" + - "# HELP jvm_memory_pool_collection_init_bytes Initial after last collection bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_collection_init_bytes{pool=\"PS Eden Space\"} 21.0\n" + - "jvm_memory_pool_collection_init_bytes{pool=\"PS Old Gen\"} 25.0\n" + - "# TYPE jvm_memory_pool_collection_max_bytes gauge\n" + - "# UNIT jvm_memory_pool_collection_max_bytes bytes\n" + - "# HELP jvm_memory_pool_collection_max_bytes Max bytes after last collection of a given JVM memory pool.\n" + - "jvm_memory_pool_collection_max_bytes{pool=\"PS Eden Space\"} 19.0\n" + - "jvm_memory_pool_collection_max_bytes{pool=\"PS Old Gen\"} 23.0\n" + - "# TYPE jvm_memory_pool_collection_used_bytes gauge\n" + - "# UNIT jvm_memory_pool_collection_used_bytes bytes\n" + - "# HELP jvm_memory_pool_collection_used_bytes Used bytes after last collection of a given JVM memory pool.\n" + - "jvm_memory_pool_collection_used_bytes{pool=\"PS Eden Space\"} 18.0\n" + - "jvm_memory_pool_collection_used_bytes{pool=\"PS Old Gen\"} 22.0\n" + - "# TYPE jvm_memory_pool_committed_bytes gauge\n" + - "# UNIT jvm_memory_pool_committed_bytes bytes\n" + - "# HELP jvm_memory_pool_committed_bytes Committed bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_committed_bytes{pool=\"PS Eden Space\"} 12.0\n" + - "jvm_memory_pool_committed_bytes{pool=\"PS Old Gen\"} 16.0\n" + - "# TYPE jvm_memory_pool_init_bytes gauge\n" + - "# UNIT jvm_memory_pool_init_bytes bytes\n" + - "# HELP jvm_memory_pool_init_bytes Initial bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_init_bytes{pool=\"PS Eden Space\"} 13.0\n" + - "jvm_memory_pool_init_bytes{pool=\"PS Old Gen\"} 17.0\n" + - "# TYPE jvm_memory_pool_max_bytes gauge\n" + - "# UNIT jvm_memory_pool_max_bytes bytes\n" + - "# HELP jvm_memory_pool_max_bytes Max bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_max_bytes{pool=\"PS Eden Space\"} 11.0\n" + - "jvm_memory_pool_max_bytes{pool=\"PS Old Gen\"} 15.0\n" + - "# TYPE jvm_memory_pool_used_bytes gauge\n" + - "# UNIT jvm_memory_pool_used_bytes bytes\n" + - "# HELP jvm_memory_pool_used_bytes Used bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_used_bytes{pool=\"PS Eden Space\"} 10.0\n" + - "jvm_memory_pool_used_bytes{pool=\"PS Old Gen\"} 14.0\n" + - "# TYPE jvm_memory_used_bytes gauge\n" + - "# UNIT jvm_memory_used_bytes bytes\n" + - "# HELP jvm_memory_used_bytes Used bytes of a given JVM memory area.\n" + - "jvm_memory_used_bytes{area=\"heap\"} 2.0\n" + - "jvm_memory_used_bytes{area=\"nonheap\"} 6.0\n" + - "# EOF\n"; - - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } - - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_memory_pool_used_bytes") - .build(); - - PrometheusRegistry registry = new PrometheusRegistry(); - JvmMemoryMetrics.builder() - .withMemoryBean(mockMemoryBean) - .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) - .register(registry); - registry.scrape(filter); - - verify(memoryUsagePoolEdenSpace, times(0)).getUsed(); - verify(memoryUsagePoolOldGen, times(0)).getUsed(); - verify(memoryUsagePoolEdenSpace, times(1)).getMax(); - verify(memoryUsagePoolOldGen, times(1)).getMax(); - } + private final MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class); + private final MemoryPoolMXBean mockPoolsBeanEdenSpace = Mockito.mock(MemoryPoolMXBean.class); + private final MemoryPoolMXBean mockPoolsBeanOldGen = Mockito.mock(MemoryPoolMXBean.class); + private final MemoryUsage memoryUsageHeap = Mockito.mock(MemoryUsage.class); + private final MemoryUsage memoryUsageNonHeap = Mockito.mock(MemoryUsage.class); + private final MemoryUsage memoryUsagePoolEdenSpace = Mockito.mock(MemoryUsage.class); + private final MemoryUsage memoryUsagePoolOldGen = Mockito.mock(MemoryUsage.class); + private final MemoryUsage memoryUsagePoolCollectionEdenSpace = Mockito.mock(MemoryUsage.class); + private final MemoryUsage memoryUsagePoolCollectionOldGen = Mockito.mock(MemoryUsage.class); + + @Before + public void setUp() { + when(mockMemoryBean.getHeapMemoryUsage()).thenReturn(memoryUsageHeap); + when(mockMemoryBean.getNonHeapMemoryUsage()).thenReturn(memoryUsageNonHeap); + + long val = 1L; + when(mockMemoryBean.getObjectPendingFinalizationCount()).thenReturn((int) val++); + + when(memoryUsageHeap.getUsed()).thenReturn(val++); + when(memoryUsageHeap.getMax()).thenReturn(val++); + when(memoryUsageHeap.getCommitted()).thenReturn(val++); + when(memoryUsageHeap.getInit()).thenReturn(val++); + + when(memoryUsageNonHeap.getUsed()).thenReturn(val++); + when(memoryUsageNonHeap.getMax()).thenReturn(val++); + when(memoryUsageNonHeap.getCommitted()).thenReturn(val++); + when(memoryUsageNonHeap.getInit()).thenReturn(val++); + + when(memoryUsagePoolEdenSpace.getUsed()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getMax()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getCommitted()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getInit()).thenReturn(val++); + + when(memoryUsagePoolOldGen.getUsed()).thenReturn(val++); + when(memoryUsagePoolOldGen.getMax()).thenReturn(val++); + when(memoryUsagePoolOldGen.getCommitted()).thenReturn(val++); + when(memoryUsagePoolOldGen.getInit()).thenReturn(val++); + + when(memoryUsagePoolCollectionEdenSpace.getUsed()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getMax()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getCommitted()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getInit()).thenReturn(val++); + + when(memoryUsagePoolCollectionOldGen.getUsed()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getMax()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getCommitted()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getInit()).thenReturn(val++); + + when(mockPoolsBeanEdenSpace.getName()).thenReturn("PS Eden Space"); + when(mockPoolsBeanEdenSpace.getUsage()).thenReturn(memoryUsagePoolEdenSpace); + when(mockPoolsBeanEdenSpace.getCollectionUsage()) + .thenReturn(memoryUsagePoolCollectionEdenSpace); + + when(mockPoolsBeanOldGen.getName()).thenReturn("PS Old Gen"); + when(mockPoolsBeanOldGen.getUsage()).thenReturn(memoryUsagePoolOldGen); + when(mockPoolsBeanOldGen.getCollectionUsage()).thenReturn(memoryUsagePoolCollectionOldGen); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmMemoryMetrics.builder() + .withMemoryBean(mockMemoryBean) + .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = + "# TYPE jvm_memory_committed_bytes gauge\n" + + "# UNIT jvm_memory_committed_bytes bytes\n" + + "# HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.\n" + + "jvm_memory_committed_bytes{area=\"heap\"} 4.0\n" + + "jvm_memory_committed_bytes{area=\"nonheap\"} 8.0\n" + + "# TYPE jvm_memory_init_bytes gauge\n" + + "# UNIT jvm_memory_init_bytes bytes\n" + + "# HELP jvm_memory_init_bytes Initial bytes of a given JVM memory area.\n" + + "jvm_memory_init_bytes{area=\"heap\"} 5.0\n" + + "jvm_memory_init_bytes{area=\"nonheap\"} 9.0\n" + + "# TYPE jvm_memory_max_bytes gauge\n" + + "# UNIT jvm_memory_max_bytes bytes\n" + + "# HELP jvm_memory_max_bytes Max (bytes) of a given JVM memory area.\n" + + "jvm_memory_max_bytes{area=\"heap\"} 3.0\n" + + "jvm_memory_max_bytes{area=\"nonheap\"} 7.0\n" + + "# TYPE jvm_memory_objects_pending_finalization gauge\n" + + "# HELP jvm_memory_objects_pending_finalization The number of objects waiting in the finalizer queue.\n" + + "jvm_memory_objects_pending_finalization 1.0\n" + + "# TYPE jvm_memory_pool_collection_committed_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_committed_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_committed_bytes Committed after last collection bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_committed_bytes{pool=\"PS Eden Space\"} 20.0\n" + + "jvm_memory_pool_collection_committed_bytes{pool=\"PS Old Gen\"} 24.0\n" + + "# TYPE jvm_memory_pool_collection_init_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_init_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_init_bytes Initial after last collection bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_init_bytes{pool=\"PS Eden Space\"} 21.0\n" + + "jvm_memory_pool_collection_init_bytes{pool=\"PS Old Gen\"} 25.0\n" + + "# TYPE jvm_memory_pool_collection_max_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_max_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_max_bytes Max bytes after last collection of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_max_bytes{pool=\"PS Eden Space\"} 19.0\n" + + "jvm_memory_pool_collection_max_bytes{pool=\"PS Old Gen\"} 23.0\n" + + "# TYPE jvm_memory_pool_collection_used_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_used_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_used_bytes Used bytes after last collection of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_used_bytes{pool=\"PS Eden Space\"} 18.0\n" + + "jvm_memory_pool_collection_used_bytes{pool=\"PS Old Gen\"} 22.0\n" + + "# TYPE jvm_memory_pool_committed_bytes gauge\n" + + "# UNIT jvm_memory_pool_committed_bytes bytes\n" + + "# HELP jvm_memory_pool_committed_bytes Committed bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_committed_bytes{pool=\"PS Eden Space\"} 12.0\n" + + "jvm_memory_pool_committed_bytes{pool=\"PS Old Gen\"} 16.0\n" + + "# TYPE jvm_memory_pool_init_bytes gauge\n" + + "# UNIT jvm_memory_pool_init_bytes bytes\n" + + "# HELP jvm_memory_pool_init_bytes Initial bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_init_bytes{pool=\"PS Eden Space\"} 13.0\n" + + "jvm_memory_pool_init_bytes{pool=\"PS Old Gen\"} 17.0\n" + + "# TYPE jvm_memory_pool_max_bytes gauge\n" + + "# UNIT jvm_memory_pool_max_bytes bytes\n" + + "# HELP jvm_memory_pool_max_bytes Max bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_max_bytes{pool=\"PS Eden Space\"} 11.0\n" + + "jvm_memory_pool_max_bytes{pool=\"PS Old Gen\"} 15.0\n" + + "# TYPE jvm_memory_pool_used_bytes gauge\n" + + "# UNIT jvm_memory_pool_used_bytes bytes\n" + + "# HELP jvm_memory_pool_used_bytes Used bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_used_bytes{pool=\"PS Eden Space\"} 10.0\n" + + "jvm_memory_pool_used_bytes{pool=\"PS Old Gen\"} 14.0\n" + + "# TYPE jvm_memory_used_bytes gauge\n" + + "# UNIT jvm_memory_used_bytes bytes\n" + + "# HELP jvm_memory_used_bytes Used bytes of a given JVM memory area.\n" + + "jvm_memory_used_bytes{area=\"heap\"} 2.0\n" + + "jvm_memory_used_bytes{area=\"nonheap\"} 6.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_memory_pool_used_bytes").build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmMemoryMetrics.builder() + .withMemoryBean(mockMemoryBean) + .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) + .register(registry); + registry.scrape(filter); + + verify(memoryUsagePoolEdenSpace, times(0)).getUsed(); + verify(memoryUsagePoolOldGen, times(0)).getUsed(); + verify(memoryUsagePoolEdenSpace, times(1)).getMax(); + verify(memoryUsagePoolOldGen, times(1)).getMax(); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java index d93b1682d..f0df40538 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java @@ -1,19 +1,19 @@ package io.prometheus.metrics.instrumentation.jvm; -import io.prometheus.metrics.model.registry.PrometheusRegistry; -import org.junit.Test; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import org.junit.Test; + public class JvmMetricsTest { - @Test - public void testRegisterIdempotent() { - PrometheusRegistry registry = new PrometheusRegistry(); - assertEquals(0, registry.scrape().size()); - JvmMetrics.builder().register(registry); - assertTrue(registry.scrape().size() > 0); - JvmMetrics.builder().register(registry); - } + @Test + public void testRegisterIdempotent() { + PrometheusRegistry registry = new PrometheusRegistry(); + assertEquals(0, registry.scrape().size()); + JvmMetrics.builder().register(registry); + assertTrue(registry.scrape().size() > 0); + JvmMetrics.builder().register(registry); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java index 753860d78..ca9ddca29 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java @@ -1,24 +1,24 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; -import java.io.IOException; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.when; - public class JvmNativeMemoryMetricsTest { @Test public void testNativeMemoryTrackingFail() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); - JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = + Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); when(adapter.vmNativeMemorySummaryInBytes()).thenThrow(new RuntimeException("mock")); PrometheusRegistry registry = new PrometheusRegistry(); @@ -34,7 +34,8 @@ public void testNativeMemoryTrackingFail() throws IOException { public void testNativeMemoryTrackingEmpty() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); - JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = + Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); when(adapter.vmNativeMemorySummaryInBytes()).thenReturn(""); PrometheusRegistry registry = new PrometheusRegistry(); @@ -50,8 +51,10 @@ public void testNativeMemoryTrackingEmpty() throws IOException { public void testNativeMemoryTrackingDisabled() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); - JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); - when(adapter.vmNativeMemorySummaryInBytes()).thenReturn("Native memory tracking is not enabled"); + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = + Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + when(adapter.vmNativeMemorySummaryInBytes()) + .thenReturn("Native memory tracking is not enabled"); PrometheusRegistry registry = new PrometheusRegistry(); new JvmNativeMemoryMetrics.Builder(PrometheusProperties.get(), adapter).register(registry); @@ -66,159 +69,160 @@ public void testNativeMemoryTrackingDisabled() throws IOException { public void testNativeMemoryTrackingEnabled() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); - JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); - when(adapter.vmNativeMemorySummaryInBytes()).thenReturn( - "Native Memory Tracking:\n" + - "\n" + - "Total: reserved=10341970661, committed=642716389\n" + - " malloc: 27513573 #22947\n" + - " mmap: reserved=10314457088, committed=615202816\n" + - "\n" + - "- Java Heap (reserved=8531214336, committed=536870912)\n" + - " (mmap: reserved=8531214336, committed=536870912) \n" + - " \n" + - "- Class (reserved=1073899939, committed=616867)\n" + - " (classes #1630)\n" + - " ( instance classes #1462, array classes #168)\n" + - " (malloc=158115 #2350) \n" + - " (mmap: reserved=1073741824, committed=458752) \n" + - " ( Metadata: )\n" + - " ( reserved=67108864, committed=2818048)\n" + - " ( used=2748008)\n" + - " ( waste=70040 =2.49%)\n" + - " ( Class space:)\n" + - " ( reserved=1073741824, committed=458752)\n" + - " ( used=343568)\n" + - " ( waste=115184 =25.11%)\n" + - " \n" + - "- Thread (reserved=21020080, committed=847280)\n" + - " (thread #20)\n" + - " (stack: reserved=20971520, committed=798720)\n" + - " (malloc=27512 #125) \n" + - " (arena=21048 #37)\n" + - " \n" + - "- Code (reserved=253796784, committed=7836080)\n" + - " (malloc=105944 #1403) \n" + - " (mmap: reserved=253689856, committed=7729152) \n" + - " (arena=984 #1)\n" + - " \n" + - "- GC (reserved=373343252, committed=76530708)\n" + - " (malloc=22463508 #720) \n" + - " (mmap: reserved=350879744, committed=54067200) \n" + - " \n" + - "- Compiler (reserved=1926356, committed=1926356)\n" + - " (malloc=20428 #73) \n" + - " (arena=1905928 #20)\n" + - " \n" + - "- Internal (reserved=242257, committed=242257)\n" + - " (malloc=176721 #1808) \n" + - " (mmap: reserved=65536, committed=65536) \n" + - " \n" + - "- Other (reserved=4096, committed=4096)\n" + - " (malloc=4096 #2) \n" + - " \n" + - "- Symbol (reserved=1505072, committed=1505072)\n" + - " (malloc=1136432 #14482) \n" + - " (arena=368640 #1)\n" + - " \n" + - "- Native Memory Tracking (reserved=373448, committed=373448)\n" + - " (malloc=6280 #91) \n" + - " (tracking overhead=367168)\n" + - " \n" + - "- Shared class space (reserved=16777216, committed=12386304)\n" + - " (mmap: reserved=16777216, committed=12386304) \n" + - " \n" + - "- Arena Chunk (reserved=503216, committed=503216)\n" + - " (malloc=503216) \n" + - " \n" + - "- Tracing (reserved=33097, committed=33097)\n" + - " (malloc=369 #10) \n" + - " (arena=32728 #1)\n" + - " \n" + - "- Arguments (reserved=160, committed=160)\n" + - " (malloc=160 #5) \n" + - " \n" + - "- Module (reserved=169168, committed=169168)\n" + - " (malloc=169168 #1266) \n" + - " \n" + - "- Safepoint (reserved=8192, committed=8192)\n" + - " (mmap: reserved=8192, committed=8192) \n" + - " \n" + - "- Synchronization (reserved=31160, committed=31160)\n" + - " (malloc=31160 #452) \n" + - " \n" + - "- Serviceability (reserved=600, committed=600)\n" + - " (malloc=600 #6) \n" + - " \n" + - "- Metaspace (reserved=67120768, committed=2829952)\n" + - " (malloc=11904 #12) \n" + - " (mmap: reserved=67108864, committed=2818048) \n" + - " \n" + - "- String Deduplication (reserved=632, committed=632)\n" + - " (malloc=632 #8) \n" + - " \n" + - "- Object Monitors (reserved=832, committed=832)\n" + - " (malloc=832 #4) \n" + - " \n" + - "\n" - ); + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = + Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + when(adapter.vmNativeMemorySummaryInBytes()) + .thenReturn( + "Native Memory Tracking:\n" + + "\n" + + "Total: reserved=10341970661, committed=642716389\n" + + " malloc: 27513573 #22947\n" + + " mmap: reserved=10314457088, committed=615202816\n" + + "\n" + + "- Java Heap (reserved=8531214336, committed=536870912)\n" + + " (mmap: reserved=8531214336, committed=536870912) \n" + + " \n" + + "- Class (reserved=1073899939, committed=616867)\n" + + " (classes #1630)\n" + + " ( instance classes #1462, array classes #168)\n" + + " (malloc=158115 #2350) \n" + + " (mmap: reserved=1073741824, committed=458752) \n" + + " ( Metadata: )\n" + + " ( reserved=67108864, committed=2818048)\n" + + " ( used=2748008)\n" + + " ( waste=70040 =2.49%)\n" + + " ( Class space:)\n" + + " ( reserved=1073741824, committed=458752)\n" + + " ( used=343568)\n" + + " ( waste=115184 =25.11%)\n" + + " \n" + + "- Thread (reserved=21020080, committed=847280)\n" + + " (thread #20)\n" + + " (stack: reserved=20971520, committed=798720)\n" + + " (malloc=27512 #125) \n" + + " (arena=21048 #37)\n" + + " \n" + + "- Code (reserved=253796784, committed=7836080)\n" + + " (malloc=105944 #1403) \n" + + " (mmap: reserved=253689856, committed=7729152) \n" + + " (arena=984 #1)\n" + + " \n" + + "- GC (reserved=373343252, committed=76530708)\n" + + " (malloc=22463508 #720) \n" + + " (mmap: reserved=350879744, committed=54067200) \n" + + " \n" + + "- Compiler (reserved=1926356, committed=1926356)\n" + + " (malloc=20428 #73) \n" + + " (arena=1905928 #20)\n" + + " \n" + + "- Internal (reserved=242257, committed=242257)\n" + + " (malloc=176721 #1808) \n" + + " (mmap: reserved=65536, committed=65536) \n" + + " \n" + + "- Other (reserved=4096, committed=4096)\n" + + " (malloc=4096 #2) \n" + + " \n" + + "- Symbol (reserved=1505072, committed=1505072)\n" + + " (malloc=1136432 #14482) \n" + + " (arena=368640 #1)\n" + + " \n" + + "- Native Memory Tracking (reserved=373448, committed=373448)\n" + + " (malloc=6280 #91) \n" + + " (tracking overhead=367168)\n" + + " \n" + + "- Shared class space (reserved=16777216, committed=12386304)\n" + + " (mmap: reserved=16777216, committed=12386304) \n" + + " \n" + + "- Arena Chunk (reserved=503216, committed=503216)\n" + + " (malloc=503216) \n" + + " \n" + + "- Tracing (reserved=33097, committed=33097)\n" + + " (malloc=369 #10) \n" + + " (arena=32728 #1)\n" + + " \n" + + "- Arguments (reserved=160, committed=160)\n" + + " (malloc=160 #5) \n" + + " \n" + + "- Module (reserved=169168, committed=169168)\n" + + " (malloc=169168 #1266) \n" + + " \n" + + "- Safepoint (reserved=8192, committed=8192)\n" + + " (mmap: reserved=8192, committed=8192) \n" + + " \n" + + "- Synchronization (reserved=31160, committed=31160)\n" + + " (malloc=31160 #452) \n" + + " \n" + + "- Serviceability (reserved=600, committed=600)\n" + + " (malloc=600 #6) \n" + + " \n" + + "- Metaspace (reserved=67120768, committed=2829952)\n" + + " (malloc=11904 #12) \n" + + " (mmap: reserved=67108864, committed=2818048) \n" + + " \n" + + "- String Deduplication (reserved=632, committed=632)\n" + + " (malloc=632 #8) \n" + + " \n" + + "- Object Monitors (reserved=832, committed=832)\n" + + " (malloc=832 #4) \n" + + " \n" + + "\n"); PrometheusRegistry registry = new PrometheusRegistry(); new JvmNativeMemoryMetrics.Builder(PrometheusProperties.get(), adapter).register(registry); MetricSnapshots snapshots = registry.scrape(); String expected = - "# TYPE jvm_native_memory_committed_bytes gauge\n" + - "# UNIT jvm_native_memory_committed_bytes bytes\n" + - "# HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.\n" + - "jvm_native_memory_committed_bytes{pool=\"Arena Chunk\"} 503216.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Arguments\"} 160.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Class\"} 616867.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Code\"} 7836080.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Compiler\"} 1926356.0\n" + - "jvm_native_memory_committed_bytes{pool=\"GC\"} 7.6530708E7\n" + - "jvm_native_memory_committed_bytes{pool=\"Internal\"} 242257.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Java Heap\"} 5.36870912E8\n" + - "jvm_native_memory_committed_bytes{pool=\"Metaspace\"} 2829952.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Module\"} 169168.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Object Monitors\"} 832.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Other\"} 4096.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Safepoint\"} 8192.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Serviceability\"} 600.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Shared class space\"} 1.2386304E7\n" + - "jvm_native_memory_committed_bytes{pool=\"String Deduplication\"} 632.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Symbol\"} 1505072.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Synchronization\"} 31160.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Thread\"} 847280.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Total\"} 6.42716389E8\n" + - "jvm_native_memory_committed_bytes{pool=\"Tracing\"} 33097.0\n" + - "# TYPE jvm_native_memory_reserved_bytes gauge\n" + - "# UNIT jvm_native_memory_reserved_bytes bytes\n" + - "# HELP jvm_native_memory_reserved_bytes Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.\n" + - "jvm_native_memory_reserved_bytes{pool=\"Arena Chunk\"} 503216.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Arguments\"} 160.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Class\"} 1.073899939E9\n" + - "jvm_native_memory_reserved_bytes{pool=\"Code\"} 2.53796784E8\n" + - "jvm_native_memory_reserved_bytes{pool=\"Compiler\"} 1926356.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"GC\"} 3.73343252E8\n" + - "jvm_native_memory_reserved_bytes{pool=\"Internal\"} 242257.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Java Heap\"} 8.531214336E9\n" + - "jvm_native_memory_reserved_bytes{pool=\"Metaspace\"} 6.7120768E7\n" + - "jvm_native_memory_reserved_bytes{pool=\"Module\"} 169168.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Object Monitors\"} 832.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Other\"} 4096.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Safepoint\"} 8192.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Serviceability\"} 600.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Shared class space\"} 1.6777216E7\n" + - "jvm_native_memory_reserved_bytes{pool=\"String Deduplication\"} 632.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Symbol\"} 1505072.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Synchronization\"} 31160.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Thread\"} 2.102008E7\n" + - "jvm_native_memory_reserved_bytes{pool=\"Total\"} 1.0341970661E10\n" + - "jvm_native_memory_reserved_bytes{pool=\"Tracing\"} 33097.0\n" + - "# EOF\n"; + "# TYPE jvm_native_memory_committed_bytes gauge\n" + + "# UNIT jvm_native_memory_committed_bytes bytes\n" + + "# HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.\n" + + "jvm_native_memory_committed_bytes{pool=\"Arena Chunk\"} 503216.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Arguments\"} 160.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Class\"} 616867.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Code\"} 7836080.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Compiler\"} 1926356.0\n" + + "jvm_native_memory_committed_bytes{pool=\"GC\"} 7.6530708E7\n" + + "jvm_native_memory_committed_bytes{pool=\"Internal\"} 242257.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Java Heap\"} 5.36870912E8\n" + + "jvm_native_memory_committed_bytes{pool=\"Metaspace\"} 2829952.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Module\"} 169168.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Object Monitors\"} 832.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Other\"} 4096.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Safepoint\"} 8192.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Serviceability\"} 600.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Shared class space\"} 1.2386304E7\n" + + "jvm_native_memory_committed_bytes{pool=\"String Deduplication\"} 632.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Symbol\"} 1505072.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Synchronization\"} 31160.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Thread\"} 847280.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Total\"} 6.42716389E8\n" + + "jvm_native_memory_committed_bytes{pool=\"Tracing\"} 33097.0\n" + + "# TYPE jvm_native_memory_reserved_bytes gauge\n" + + "# UNIT jvm_native_memory_reserved_bytes bytes\n" + + "# HELP jvm_native_memory_reserved_bytes Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.\n" + + "jvm_native_memory_reserved_bytes{pool=\"Arena Chunk\"} 503216.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Arguments\"} 160.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Class\"} 1.073899939E9\n" + + "jvm_native_memory_reserved_bytes{pool=\"Code\"} 2.53796784E8\n" + + "jvm_native_memory_reserved_bytes{pool=\"Compiler\"} 1926356.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"GC\"} 3.73343252E8\n" + + "jvm_native_memory_reserved_bytes{pool=\"Internal\"} 242257.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Java Heap\"} 8.531214336E9\n" + + "jvm_native_memory_reserved_bytes{pool=\"Metaspace\"} 6.7120768E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"Module\"} 169168.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Object Monitors\"} 832.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Other\"} 4096.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Safepoint\"} 8192.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Serviceability\"} 600.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Shared class space\"} 1.6777216E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"String Deduplication\"} 632.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Symbol\"} 1505072.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Synchronization\"} 31160.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Thread\"} 2.102008E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"Total\"} 1.0341970661E10\n" + + "jvm_native_memory_reserved_bytes{pool=\"Tracing\"} 33097.0\n" + + "# EOF\n"; Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java index 4f2d7d5ee..dc39bf455 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java @@ -1,32 +1,31 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; + import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; import org.junit.Assert; import org.junit.Test; -import java.io.IOException; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; - public class JvmRuntimeInfoMetricTest { - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmRuntimeInfoMetric.builder() - .version("1.8.0_382-b05") - .vendor("Oracle Corporation") - .runtime("OpenJDK Runtime Environment") - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmRuntimeInfoMetric.builder() + .version("1.8.0_382-b05") + .vendor("Oracle Corporation") + .runtime("OpenJDK Runtime Environment") + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - String expected = - "# TYPE jvm_runtime info\n" + - "# HELP jvm_runtime JVM runtime info\n" + - "jvm_runtime_info{runtime=\"OpenJDK Runtime Environment\",vendor=\"Oracle Corporation\",version=\"1.8.0_382-b05\"} 1\n" + - "# EOF\n"; + String expected = + "# TYPE jvm_runtime info\n" + + "# HELP jvm_runtime JVM runtime info\n" + + "jvm_runtime_info{runtime=\"OpenJDK Runtime Environment\",vendor=\"Oracle Corporation\",version=\"1.8.0_382-b05\"} 1\n" + + "# EOF\n"; - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java index eed4a9421..03494a269 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java @@ -1,200 +1,198 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import java.io.IOException; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; public class JvmThreadsMetricsTest { - private final ThreadMXBean mockThreadsBean = Mockito.mock(ThreadMXBean.class); - private final ThreadInfo mockThreadInfoBlocked = Mockito.mock(ThreadInfo.class); - private final ThreadInfo mockThreadInfoRunnable1 = Mockito.mock(ThreadInfo.class); - private final ThreadInfo mockThreadInfoRunnable2 = Mockito.mock(ThreadInfo.class); - - @Before - public void setUp() { - when(mockThreadsBean.getThreadCount()).thenReturn(300); - when(mockThreadsBean.getDaemonThreadCount()).thenReturn(200); - when(mockThreadsBean.getPeakThreadCount()).thenReturn(301); - when(mockThreadsBean.getTotalStartedThreadCount()).thenReturn(503L); - when(mockThreadsBean.findDeadlockedThreads()).thenReturn(new long[]{1L, 2L, 3L}); - when(mockThreadsBean.findMonitorDeadlockedThreads()).thenReturn(new long[]{2L, 3L, 4L}); - when(mockThreadsBean.getAllThreadIds()).thenReturn(new long[]{3L, 4L, 5L}); - when(mockThreadInfoBlocked.getThreadState()).thenReturn(Thread.State.BLOCKED); - when(mockThreadInfoRunnable1.getThreadState()).thenReturn(Thread.State.RUNNABLE); - when(mockThreadInfoRunnable2.getThreadState()).thenReturn(Thread.State.RUNNABLE); - when(mockThreadsBean.getThreadInfo(new long[]{3L, 4L, 5L}, 0)).thenReturn(new ThreadInfo[]{ - mockThreadInfoBlocked, mockThreadInfoRunnable1, mockThreadInfoRunnable2 - }); + private final ThreadMXBean mockThreadsBean = Mockito.mock(ThreadMXBean.class); + private final ThreadInfo mockThreadInfoBlocked = Mockito.mock(ThreadInfo.class); + private final ThreadInfo mockThreadInfoRunnable1 = Mockito.mock(ThreadInfo.class); + private final ThreadInfo mockThreadInfoRunnable2 = Mockito.mock(ThreadInfo.class); + + @Before + public void setUp() { + when(mockThreadsBean.getThreadCount()).thenReturn(300); + when(mockThreadsBean.getDaemonThreadCount()).thenReturn(200); + when(mockThreadsBean.getPeakThreadCount()).thenReturn(301); + when(mockThreadsBean.getTotalStartedThreadCount()).thenReturn(503L); + when(mockThreadsBean.findDeadlockedThreads()).thenReturn(new long[] {1L, 2L, 3L}); + when(mockThreadsBean.findMonitorDeadlockedThreads()).thenReturn(new long[] {2L, 3L, 4L}); + when(mockThreadsBean.getAllThreadIds()).thenReturn(new long[] {3L, 4L, 5L}); + when(mockThreadInfoBlocked.getThreadState()).thenReturn(Thread.State.BLOCKED); + when(mockThreadInfoRunnable1.getThreadState()).thenReturn(Thread.State.RUNNABLE); + when(mockThreadInfoRunnable2.getThreadState()).thenReturn(Thread.State.RUNNABLE); + when(mockThreadsBean.getThreadInfo(new long[] {3L, 4L, 5L}, 0)) + .thenReturn( + new ThreadInfo[] { + mockThreadInfoBlocked, mockThreadInfoRunnable1, mockThreadInfoRunnable2 + }); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.builder().threadBean(mockThreadsBean).isNativeImage(false).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = + "# TYPE jvm_threads_current gauge\n" + + "# HELP jvm_threads_current Current thread count of a JVM\n" + + "jvm_threads_current 300.0\n" + + "# TYPE jvm_threads_daemon gauge\n" + + "# HELP jvm_threads_daemon Daemon thread count of a JVM\n" + + "jvm_threads_daemon 200.0\n" + + "# TYPE jvm_threads_deadlocked gauge\n" + + "# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers\n" + + "jvm_threads_deadlocked 3.0\n" + + "# TYPE jvm_threads_deadlocked_monitor gauge\n" + + "# HELP jvm_threads_deadlocked_monitor Cycles of JVM-threads that are in deadlock waiting to acquire object monitors\n" + + "jvm_threads_deadlocked_monitor 3.0\n" + + "# TYPE jvm_threads_peak gauge\n" + + "# HELP jvm_threads_peak Peak thread count of a JVM\n" + + "jvm_threads_peak 301.0\n" + + "# TYPE jvm_threads_started counter\n" + + "# HELP jvm_threads_started Started thread count of a JVM\n" + + "jvm_threads_started_total 503.0\n" + + "# TYPE jvm_threads_state gauge\n" + + "# HELP jvm_threads_state Current count of threads by state\n" + + "jvm_threads_state{state=\"BLOCKED\"} 1.0\n" + + "jvm_threads_state{state=\"NEW\"} 0.0\n" + + "jvm_threads_state{state=\"RUNNABLE\"} 2.0\n" + + "jvm_threads_state{state=\"TERMINATED\"} 0.0\n" + + "jvm_threads_state{state=\"TIMED_WAITING\"} 0.0\n" + + "jvm_threads_state{state=\"UNKNOWN\"} 0.0\n" + + "jvm_threads_state{state=\"WAITING\"} 0.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_threads_deadlocked").build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.builder().threadBean(mockThreadsBean).isNativeImage(false).register(registry); + registry.scrape(filter); + + verify(mockThreadsBean, times(0)).findDeadlockedThreads(); + verify(mockThreadsBean, times(1)).getThreadCount(); + } + + @Test + public void testInvalidThreadIds() { + try { + String javaVersion = System.getProperty("java.version"); // Example: "21.0.2" + String majorJavaVersion = javaVersion.replaceAll("\\..*", ""); // Example: "21" + if (Integer.parseInt(majorJavaVersion) >= 21) { + // With Java 21 and newer you can no longer have invalid thread ids. + return; + } + } catch (NumberFormatException ignored) { } - - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmThreadsMetrics.builder() - .threadBean(mockThreadsBean) - .isNativeImage(false) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); - - String expected = - "# TYPE jvm_threads_current gauge\n" + - "# HELP jvm_threads_current Current thread count of a JVM\n" + - "jvm_threads_current 300.0\n" + - "# TYPE jvm_threads_daemon gauge\n" + - "# HELP jvm_threads_daemon Daemon thread count of a JVM\n" + - "jvm_threads_daemon 200.0\n" + - "# TYPE jvm_threads_deadlocked gauge\n" + - "# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers\n" + - "jvm_threads_deadlocked 3.0\n" + - "# TYPE jvm_threads_deadlocked_monitor gauge\n" + - "# HELP jvm_threads_deadlocked_monitor Cycles of JVM-threads that are in deadlock waiting to acquire object monitors\n" + - "jvm_threads_deadlocked_monitor 3.0\n" + - "# TYPE jvm_threads_peak gauge\n" + - "# HELP jvm_threads_peak Peak thread count of a JVM\n" + - "jvm_threads_peak 301.0\n" + - "# TYPE jvm_threads_started counter\n" + - "# HELP jvm_threads_started Started thread count of a JVM\n" + - "jvm_threads_started_total 503.0\n" + - "# TYPE jvm_threads_state gauge\n" + - "# HELP jvm_threads_state Current count of threads by state\n" + - "jvm_threads_state{state=\"BLOCKED\"} 1.0\n" + - "jvm_threads_state{state=\"NEW\"} 0.0\n" + - "jvm_threads_state{state=\"RUNNABLE\"} 2.0\n" + - "jvm_threads_state{state=\"TERMINATED\"} 0.0\n" + - "jvm_threads_state{state=\"TIMED_WAITING\"} 0.0\n" + - "jvm_threads_state{state=\"UNKNOWN\"} 0.0\n" + - "jvm_threads_state{state=\"WAITING\"} 0.0\n" + - "# EOF\n"; - - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } - - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_threads_deadlocked") - .build(); - - PrometheusRegistry registry = new PrometheusRegistry(); - JvmThreadsMetrics.builder() - .threadBean(mockThreadsBean) - .isNativeImage(false) - .register(registry); - registry.scrape(filter); - - verify(mockThreadsBean, times(0)).findDeadlockedThreads(); - verify(mockThreadsBean, times(1)).getThreadCount(); + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.builder().register(registry); + + // Number of threads to create with invalid thread ids + int numberOfInvalidThreadIds = 2; + + Map
expected = getCountByState(registry.scrape()); + expected.compute( + "UNKNOWN", + (key, oldValue) -> + oldValue == null ? numberOfInvalidThreadIds : oldValue + numberOfInvalidThreadIds); + + final CountDownLatch countDownLatch = new CountDownLatch(numberOfInvalidThreadIds); + + try { + // Create and start threads with invalid thread ids (id=0, id=-1, etc.) + for (int i = 0; i < numberOfInvalidThreadIds; i++) { + new ThreadWithInvalidId(-i, new TestRunnable(countDownLatch)).start(); + } + + Map actual = getCountByState(registry.scrape()); + + Assert.assertEquals(expected.size(), actual.size()); + for (String threadState : expected.keySet()) { + Assert.assertEquals(expected.get(threadState), actual.get(threadState), 0.0); + } + } finally { + for (int i = 0; i < numberOfInvalidThreadIds; i++) { + countDownLatch.countDown(); + } } - - @Test - public void testInvalidThreadIds() { - try { - String javaVersion = System.getProperty("java.version"); // Example: "21.0.2" - String majorJavaVersion = javaVersion.replaceAll("\\..*", ""); // Example: "21" - if (Integer.parseInt(majorJavaVersion) >= 21) { - // With Java 21 and newer you can no longer have invalid thread ids. - return; - } - } catch (NumberFormatException ignored) { + } + + private Map getCountByState(MetricSnapshots snapshots) { + Map result = new HashMap<>(); + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getName().equals("jvm_threads_state")) { + for (GaugeSnapshot.GaugeDataPointSnapshot data : + ((GaugeSnapshot) snapshot).getDataPoints()) { + String state = data.getLabels().get("state"); + Assert.assertNotNull(state); + result.put(state, data.getValue()); } - PrometheusRegistry registry = new PrometheusRegistry(); - JvmThreadsMetrics.builder().register(registry); - - // Number of threads to create with invalid thread ids - int numberOfInvalidThreadIds = 2; - - Map expected = getCountByState(registry.scrape()); - expected.compute("UNKNOWN", (key, oldValue) -> oldValue == null ? numberOfInvalidThreadIds : oldValue + numberOfInvalidThreadIds); - - final CountDownLatch countDownLatch = new CountDownLatch(numberOfInvalidThreadIds); + } + } + return result; + } - try { - // Create and start threads with invalid thread ids (id=0, id=-1, etc.) - for (int i = 0; i < numberOfInvalidThreadIds; i++) { - new ThreadWithInvalidId(-i, new TestRunnable(countDownLatch)).start(); - } + private static class ThreadWithInvalidId extends Thread { - Map actual = getCountByState(registry.scrape()); + private final long id; - Assert.assertEquals(expected.size(), actual.size()); - for (String threadState : expected.keySet()) { - Assert.assertEquals(expected.get(threadState), actual.get(threadState), 0.0); - } - } finally { - for (int i = 0; i < numberOfInvalidThreadIds; i++) { - countDownLatch.countDown(); - } - } + public ThreadWithInvalidId(long id, Runnable runnable) { + super(runnable); + setDaemon(true); + this.id = id; } - private Map getCountByState(MetricSnapshots snapshots) { - Map result = new HashMap<>(); - for (MetricSnapshot snapshot : snapshots) { - if (snapshot.getMetadata().getName().equals("jvm_threads_state")) { - for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getDataPoints()) { - String state = data.getLabels().get("state"); - Assert.assertNotNull(state); - result.put(state, data.getValue()); - } - } - } - return result; + /** + * Note that only Java versions < 21 call this to get the thread id. With Java 21 and newer it's + * no longer possible to make an invalid thread id. + */ + @Override + public long getId() { + return this.id; } + } - private static class ThreadWithInvalidId extends Thread { - - private final long id; + private static class TestRunnable implements Runnable { - public ThreadWithInvalidId(long id, Runnable runnable) { - super(runnable); - setDaemon(true); - this.id = id; - } + private final CountDownLatch countDownLatch; - /** - * Note that only Java versions < 21 call this to get the thread id. - * With Java 21 and newer it's no longer possible to make an invalid thread id. - */ - @Override - public long getId() { - return this.id; - } + public TestRunnable(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; } - private static class TestRunnable implements Runnable { - - private final CountDownLatch countDownLatch; - - public TestRunnable(CountDownLatch countDownLatch) { - this.countDownLatch = countDownLatch; - } - - @Override - public void run() { - try { - countDownLatch.await(); - } catch (InterruptedException e) { - // DO NOTHING - } - } + @Override + public void run() { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + // DO NOTHING + } } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java index 2673f38a7..ad00e84c7 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java @@ -1,123 +1,125 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import java.io.File; import java.io.IOException; import java.lang.management.RuntimeMXBean; import java.util.concurrent.TimeUnit; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; public class ProcessMetricsTest { - private final com.sun.management.UnixOperatingSystemMXBean sunOsBean = Mockito.mock(com.sun.management.UnixOperatingSystemMXBean.class); - private final java.lang.management.OperatingSystemMXBean javaOsBean = Mockito.mock(java.lang.management.OperatingSystemMXBean.class); - private final ProcessMetrics.Grepper linuxGrepper = Mockito.mock(ProcessMetrics.Grepper.class); - private final ProcessMetrics.Grepper windowsGrepper = Mockito.mock(ProcessMetrics.Grepper.class); - private final RuntimeMXBean runtimeBean = Mockito.mock(RuntimeMXBean.class); - - @Before - public void setUp() throws IOException { - when(sunOsBean.getProcessCpuTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(72)); - when(sunOsBean.getOpenFileDescriptorCount()).thenReturn(127L); - when(sunOsBean.getMaxFileDescriptorCount()).thenReturn(244L); - when(runtimeBean.getStartTime()).thenReturn(37100L); - when(linuxGrepper.lineStartingWith(any(File.class), eq("VmSize:"))).thenReturn("VmSize: 6036 kB"); - when(linuxGrepper.lineStartingWith(any(File.class), eq("VmRSS:"))).thenReturn("VmRSS: 1012 kB"); - } + private final com.sun.management.UnixOperatingSystemMXBean sunOsBean = + Mockito.mock(com.sun.management.UnixOperatingSystemMXBean.class); + private final java.lang.management.OperatingSystemMXBean javaOsBean = + Mockito.mock(java.lang.management.OperatingSystemMXBean.class); + private final ProcessMetrics.Grepper linuxGrepper = Mockito.mock(ProcessMetrics.Grepper.class); + private final ProcessMetrics.Grepper windowsGrepper = Mockito.mock(ProcessMetrics.Grepper.class); + private final RuntimeMXBean runtimeBean = Mockito.mock(RuntimeMXBean.class); - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - ProcessMetrics.builder() - .osBean(sunOsBean) - .runtimeBean(runtimeBean) - .grepper(linuxGrepper) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Before + public void setUp() throws IOException { + when(sunOsBean.getProcessCpuTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(72)); + when(sunOsBean.getOpenFileDescriptorCount()).thenReturn(127L); + when(sunOsBean.getMaxFileDescriptorCount()).thenReturn(244L); + when(runtimeBean.getStartTime()).thenReturn(37100L); + when(linuxGrepper.lineStartingWith(any(File.class), eq("VmSize:"))) + .thenReturn("VmSize: 6036 kB"); + when(linuxGrepper.lineStartingWith(any(File.class), eq("VmRSS:"))) + .thenReturn("VmRSS: 1012 kB"); + } - String expected = - "# TYPE process_cpu_seconds counter\n" + - "# UNIT process_cpu_seconds seconds\n" + - "# HELP process_cpu_seconds Total user and system CPU time spent in seconds.\n" + - "process_cpu_seconds_total 0.072\n" + - "# TYPE process_max_fds gauge\n" + - "# HELP process_max_fds Maximum number of open file descriptors.\n" + - "process_max_fds 244.0\n" + - "# TYPE process_open_fds gauge\n" + - "# HELP process_open_fds Number of open file descriptors.\n" + - "process_open_fds 127.0\n"; - if (ProcessMetrics.PROC_SELF_STATUS.canRead()) { - expected += - "# TYPE process_resident_memory_bytes gauge\n" + - "# UNIT process_resident_memory_bytes bytes\n" + - "# HELP process_resident_memory_bytes Resident memory size in bytes.\n" + - "process_resident_memory_bytes 1036288.0\n"; - } - expected += - "# TYPE process_start_time_seconds gauge\n" + - "# UNIT process_start_time_seconds seconds\n" + - "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + - "process_start_time_seconds 37.1\n"; - if (ProcessMetrics.PROC_SELF_STATUS.canRead()) { - expected += - "# TYPE process_virtual_memory_bytes gauge\n" + - "# UNIT process_virtual_memory_bytes bytes\n" + - "# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n" + - "process_virtual_memory_bytes 6180864.0\n"; - } - expected += "# EOF\n"; + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.builder() + .osBean(sunOsBean) + .runtimeBean(runtimeBean) + .grepper(linuxGrepper) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + String expected = + "# TYPE process_cpu_seconds counter\n" + + "# UNIT process_cpu_seconds seconds\n" + + "# HELP process_cpu_seconds Total user and system CPU time spent in seconds.\n" + + "process_cpu_seconds_total 0.072\n" + + "# TYPE process_max_fds gauge\n" + + "# HELP process_max_fds Maximum number of open file descriptors.\n" + + "process_max_fds 244.0\n" + + "# TYPE process_open_fds gauge\n" + + "# HELP process_open_fds Number of open file descriptors.\n" + + "process_open_fds 127.0\n"; + if (ProcessMetrics.PROC_SELF_STATUS.canRead()) { + expected += + "# TYPE process_resident_memory_bytes gauge\n" + + "# UNIT process_resident_memory_bytes bytes\n" + + "# HELP process_resident_memory_bytes Resident memory size in bytes.\n" + + "process_resident_memory_bytes 1036288.0\n"; + } + expected += + "# TYPE process_start_time_seconds gauge\n" + + "# UNIT process_start_time_seconds seconds\n" + + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + + "process_start_time_seconds 37.1\n"; + if (ProcessMetrics.PROC_SELF_STATUS.canRead()) { + expected += + "# TYPE process_virtual_memory_bytes gauge\n" + + "# UNIT process_virtual_memory_bytes bytes\n" + + "# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n" + + "process_virtual_memory_bytes 6180864.0\n"; } + expected += "# EOF\n"; - @Test - public void testMinimal() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - ProcessMetrics.builder() - .osBean(javaOsBean) - .runtimeBean(runtimeBean) - .grepper(windowsGrepper) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } - String expected = - "# TYPE process_start_time_seconds gauge\n" + - "# UNIT process_start_time_seconds seconds\n" + - "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + - "process_start_time_seconds 37.1\n" + - "# EOF\n"; + @Test + public void testMinimal() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.builder() + .osBean(javaOsBean) + .runtimeBean(runtimeBean) + .grepper(windowsGrepper) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + String expected = + "# TYPE process_start_time_seconds gauge\n" + + "# UNIT process_start_time_seconds seconds\n" + + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + + "process_start_time_seconds 37.1\n" + + "# EOF\n"; - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("process_max_fds") - .build(); + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } - PrometheusRegistry registry = new PrometheusRegistry(); - ProcessMetrics.builder() - .osBean(sunOsBean) - .runtimeBean(runtimeBean) - .grepper(linuxGrepper) - .register(registry); - registry.scrape(filter); + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("process_max_fds").build(); - verify(sunOsBean, times(0)).getMaxFileDescriptorCount(); - verify(sunOsBean, times(1)).getOpenFileDescriptorCount(); - } + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.builder() + .osBean(sunOsBean) + .runtimeBean(runtimeBean) + .grepper(linuxGrepper) + .register(registry); + registry.scrape(filter); + + verify(sunOsBean, times(0)).getMaxFileDescriptorCount(); + verify(sunOsBean, times(1)).getOpenFileDescriptorCount(); + } }