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 GaugeMetricFamily init = new GaugeMetricFamily( 076 "jvm_memory_bytes_init", 077 "Initial bytes of a given JVM memory area.", 078 Collections.singletonList("area")); 079 init.addMetric(Collections.singletonList("heap"), heapUsage.getInit()); 080 init.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getInit()); 081 sampleFamilies.add(init); 082 } 083 084 void addMemoryPoolMetrics(List<MetricFamilySamples> sampleFamilies) { 085 GaugeMetricFamily used = new GaugeMetricFamily( 086 "jvm_memory_pool_bytes_used", 087 "Used bytes of a given JVM memory pool.", 088 Collections.singletonList("pool")); 089 sampleFamilies.add(used); 090 GaugeMetricFamily committed = new GaugeMetricFamily( 091 "jvm_memory_pool_bytes_committed", 092 "Committed bytes of a given JVM memory pool.", 093 Collections.singletonList("pool")); 094 sampleFamilies.add(committed); 095 GaugeMetricFamily max = new GaugeMetricFamily( 096 "jvm_memory_pool_bytes_max", 097 "Max bytes of a given JVM memory pool.", 098 Collections.singletonList("pool")); 099 sampleFamilies.add(max); 100 GaugeMetricFamily init = new GaugeMetricFamily( 101 "jvm_memory_pool_bytes_init", 102 "Initial bytes of a given JVM memory pool.", 103 Collections.singletonList("pool")); 104 sampleFamilies.add(init); 105 for (final MemoryPoolMXBean pool : poolBeans) { 106 MemoryUsage poolUsage = pool.getUsage(); 107 used.addMetric( 108 Collections.singletonList(pool.getName()), 109 poolUsage.getUsed()); 110 committed.addMetric( 111 Collections.singletonList(pool.getName()), 112 poolUsage.getCommitted()); 113 max.addMetric( 114 Collections.singletonList(pool.getName()), 115 poolUsage.getMax()); 116 init.addMetric( 117 Collections.singletonList(pool.getName()), 118 poolUsage.getInit()); 119 } 120 } 121 122 public List<MetricFamilySamples> collect() { 123 List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>(); 124 addMemoryAreaMetrics(mfs); 125 addMemoryPoolMetrics(mfs); 126 return mfs; 127 } 128}