001package io.prometheus.client.hotspot; 002 003import io.prometheus.client.Collector; 004 005import java.lang.management.ManagementFactory; 006import java.lang.management.MemoryMXBean; 007import java.lang.management.MemoryPoolMXBean; 008import java.lang.management.MemoryUsage; 009import java.util.ArrayList; 010import java.util.Arrays; 011import java.util.HashMap; 012import java.util.List; 013import java.util.regex.Pattern; 014 015/** 016 * Exports metrics about JVM memory areas. 017 * <p> 018 * Example usage: 019 * <pre> 020 * {@code 021 * new MemoryPoolsExports().register(); 022 * } 023 * </pre> 024 * Example metrics being exported: 025 * <pre> 026 * jvm_memory_bytes_used{area="heap"} 2000000 027 * jvm_memory_bytes_committed{area="nonheap"} 200000 028 * jvm_memory_bytes_max{area="nonheap"} 2000000 029 * jvm_memory_pool_bytes_used{pool="PS Eden Space"} 2000 030 * </pre> 031 */ 032public class MemoryPoolsExports extends Collector { 033 private final MemoryMXBean memoryBean; 034 private final List<MemoryPoolMXBean> poolBeans; 035 036 public MemoryPoolsExports() { 037 this( 038 ManagementFactory.getMemoryMXBean(), 039 ManagementFactory.getMemoryPoolMXBeans()); 040 } 041 042 public MemoryPoolsExports(MemoryMXBean memoryBean, 043 List<MemoryPoolMXBean> poolBeans) { 044 this.memoryBean = memoryBean; 045 this.poolBeans = poolBeans; 046 } 047 048 void addMemoryAreaMetrics(List<MetricFamilySamples> sampleFamilies) { 049 MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage(); 050 MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage(); 051 ArrayList<MetricFamilySamples.Sample> usedSamples = new ArrayList<MetricFamilySamples.Sample>(); 052 usedSamples.add( 053 new MetricFamilySamples.Sample( 054 "jvm_memory_bytes_used", 055 Arrays.asList("area"), 056 Arrays.asList("heap"), 057 heapUsage.getUsed())); 058 usedSamples.add( 059 new MetricFamilySamples.Sample( 060 "jvm_memory_bytes_used", 061 Arrays.asList("area"), 062 Arrays.asList("nonheap"), 063 nonHeapUsage.getUsed())); 064 sampleFamilies.add( 065 new MetricFamilySamples( 066 "jvm_memory_bytes_used", 067 Type.GAUGE, 068 "Used bytes of a given JVM memory area.", 069 usedSamples)); 070 ArrayList<MetricFamilySamples.Sample> committedSamples = new ArrayList<MetricFamilySamples.Sample>(); 071 committedSamples.add( 072 new MetricFamilySamples.Sample( 073 "jvm_memory_bytes_committed", 074 Arrays.asList("area"), 075 Arrays.asList("heap"), 076 heapUsage.getCommitted())); 077 committedSamples.add( 078 new MetricFamilySamples.Sample( 079 "jvm_memory_bytes_committed", 080 Arrays.asList("area"), 081 Arrays.asList("nonheap"), 082 nonHeapUsage.getCommitted())); 083 sampleFamilies.add( 084 new MetricFamilySamples( 085 "jvm_memory_bytes_committed", 086 Type.GAUGE, 087 "Committed (bytes) of a given JVM memory area.", 088 committedSamples)); 089 ArrayList<MetricFamilySamples.Sample> maxSamples = new ArrayList<MetricFamilySamples.Sample>(); 090 maxSamples.add( 091 new MetricFamilySamples.Sample( 092 "jvm_memory_bytes_max", 093 Arrays.asList("area"), 094 Arrays.asList("heap"), 095 heapUsage.getMax())); 096 maxSamples.add( 097 new MetricFamilySamples.Sample( 098 "jvm_memory_bytes_max", 099 Arrays.asList("area"), 100 Arrays.asList("nonheap"), 101 nonHeapUsage.getMax())); 102 sampleFamilies.add( 103 new MetricFamilySamples( 104 "jvm_memory_bytes_max", 105 Type.GAUGE, 106 "Maximum (bytes) of a given JVM memory area.", 107 maxSamples)); 108 } 109 110 void addMemoryPoolMetrics(List<MetricFamilySamples> sampleFamilies) { 111 ArrayList<MetricFamilySamples.Sample> usedSamples = new ArrayList<MetricFamilySamples.Sample>(); 112 ArrayList<MetricFamilySamples.Sample> committedSamples = new ArrayList<MetricFamilySamples.Sample>(); 113 ArrayList<MetricFamilySamples.Sample> maxSamples = new ArrayList<MetricFamilySamples.Sample>(); 114 for (final MemoryPoolMXBean pool : poolBeans) { 115 MemoryUsage poolUsage = pool.getUsage(); 116 usedSamples.add( 117 new MetricFamilySamples.Sample( 118 "jvm_memory_pool_bytes_used", 119 Arrays.asList("pool"), 120 Arrays.asList(pool.getName()), 121 poolUsage.getUsed())); 122 committedSamples.add( 123 new MetricFamilySamples.Sample( 124 "jvm_memory_pool_bytes_committed", 125 Arrays.asList("pool"), 126 Arrays.asList(pool.getName()), 127 poolUsage.getCommitted())); 128 maxSamples.add( 129 new MetricFamilySamples.Sample( 130 "jvm_memory_pool_bytes_max", 131 Arrays.asList("pool"), 132 Arrays.asList(pool.getName()), 133 poolUsage.getMax())); 134 } 135 sampleFamilies.add( 136 new MetricFamilySamples( 137 "jvm_memory_pool_bytes_used", 138 Type.GAUGE, 139 "Used bytes of a given JVM memory pool.", 140 usedSamples)); 141 142 sampleFamilies.add( 143 new MetricFamilySamples( 144 "jvm_memory_pool_bytes_committed", 145 Type.GAUGE, 146 "Limit (bytes) of a given JVM memory pool.", 147 committedSamples)); 148 149 sampleFamilies.add( 150 new MetricFamilySamples( 151 "jvm_memory_pool_bytes_max", 152 Type.GAUGE, 153 "Max (bytes) of a given JVM memory pool.", 154 maxSamples)); 155 } 156 157 158 public List<MetricFamilySamples> collect() { 159 List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>(); 160 addMemoryAreaMetrics(mfs); 161 addMemoryPoolMetrics(mfs); 162 return mfs; 163 } 164}