001package io.prometheus.client.hotspot; 002 003import io.prometheus.client.Collector; 004import io.prometheus.client.GaugeMetricFamily; 005 006import java.lang.management.ManagementFactory; 007import java.lang.management.MemoryMXBean; 008import java.lang.management.MemoryPoolMXBean; 009import java.lang.management.MemoryUsage; 010import java.util.ArrayList; 011import java.util.Collections; 012import java.util.List; 013 014/** 015 * Exports metrics about JVM memory areas. 016 * <p> 017 * Example usage: 018 * <pre> 019 * {@code 020 * new MemoryPoolsExports().register(); 021 * } 022 * </pre> 023 * Example metrics being exported: 024 * <pre> 025 * jvm_memory_bytes_used{area="heap"} 2000000 026 * jvm_memory_bytes_committed{area="nonheap"} 200000 027 * jvm_memory_bytes_max{area="nonheap"} 2000000 028 * jvm_memory_pool_bytes_used{pool="PS Eden Space"} 2000 029 * </pre> 030 */ 031public class MemoryPoolsExports extends Collector { 032 private final MemoryMXBean memoryBean; 033 private final List<MemoryPoolMXBean> poolBeans; 034 035 public MemoryPoolsExports() { 036 this( 037 ManagementFactory.getMemoryMXBean(), 038 ManagementFactory.getMemoryPoolMXBeans()); 039 } 040 041 public MemoryPoolsExports(MemoryMXBean memoryBean, 042 List<MemoryPoolMXBean> poolBeans) { 043 this.memoryBean = memoryBean; 044 this.poolBeans = poolBeans; 045 } 046 047 void addMemoryAreaMetrics(List<MetricFamilySamples> sampleFamilies) { 048 MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage(); 049 MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage(); 050 051 GaugeMetricFamily used = new GaugeMetricFamily( 052 "jvm_memory_bytes_used", 053 "Used bytes of a given JVM memory area.", 054 Collections.singletonList("area")); 055 used.addMetric(Collections.singletonList("heap"), heapUsage.getUsed()); 056 used.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getUsed()); 057 sampleFamilies.add(used); 058 059 GaugeMetricFamily committed = new GaugeMetricFamily( 060 "jvm_memory_bytes_committed", 061 "Committed (bytes) of a given JVM memory area.", 062 Collections.singletonList("area")); 063 committed.addMetric(Collections.singletonList("heap"), heapUsage.getCommitted()); 064 committed.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getCommitted()); 065 sampleFamilies.add(committed); 066 067 GaugeMetricFamily max = new GaugeMetricFamily( 068 "jvm_memory_bytes_max", 069 "Max (bytes) of a given JVM memory area.", 070 Collections.singletonList("area")); 071 max.addMetric(Collections.singletonList("heap"), heapUsage.getMax()); 072 max.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getMax()); 073 sampleFamilies.add(max); 074 } 075 076 void addMemoryPoolMetrics(List<MetricFamilySamples> sampleFamilies) { 077 GaugeMetricFamily used = new GaugeMetricFamily( 078 "jvm_memory_pool_bytes_used", 079 "Used bytes of a given JVM memory pool.", 080 Collections.singletonList("pool")); 081 sampleFamilies.add(used); 082 GaugeMetricFamily committed = new GaugeMetricFamily( 083 "jvm_memory_pool_bytes_committed", 084 "Committed bytes of a given JVM memory pool.", 085 Collections.singletonList("pool")); 086 sampleFamilies.add(committed); 087 GaugeMetricFamily max = new GaugeMetricFamily( 088 "jvm_memory_pool_bytes_max", 089 "Max bytes of a given JVM memory pool.", 090 Collections.singletonList("pool")); 091 sampleFamilies.add(max); 092 for (final MemoryPoolMXBean pool : poolBeans) { 093 MemoryUsage poolUsage = pool.getUsage(); 094 used.addMetric( 095 Collections.singletonList(pool.getName()), 096 poolUsage.getUsed()); 097 committed.addMetric( 098 Collections.singletonList(pool.getName()), 099 poolUsage.getCommitted()); 100 max.addMetric( 101 Collections.singletonList(pool.getName()), 102 poolUsage.getMax()); 103 } 104 } 105 106 public List<MetricFamilySamples> collect() { 107 List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>(); 108 addMemoryAreaMetrics(mfs); 109 addMemoryPoolMetrics(mfs); 110 return mfs; 111 } 112}