001package io.prometheus.metrics.instrumentation.jvm; 002 003import io.prometheus.metrics.config.PrometheusProperties; 004import io.prometheus.metrics.core.metrics.GaugeWithCallback; 005import io.prometheus.metrics.model.registry.PrometheusRegistry; 006import io.prometheus.metrics.model.snapshots.Unit; 007import java.lang.management.BufferPoolMXBean; 008import java.lang.management.ManagementFactory; 009import java.util.List; 010 011/** 012 * JVM Buffer Pool metrics. The {@link JvmBufferPoolMetrics} are registered as part of the {@link 013 * JvmMetrics} like this: 014 * 015 * <pre>{@code 016 * JvmMetrics.builder().register(); 017 * }</pre> 018 * 019 * However, if you want only the {@link JvmBufferPoolMetrics} you can also register them directly: 020 * 021 * <pre>{@code 022 * JvmBufferPoolMetrics.builder().register(); 023 * }</pre> 024 * 025 * Example metrics being exported: 026 * 027 * <pre> 028 * # HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool. 029 * # TYPE jvm_buffer_pool_capacity_bytes gauge 030 * jvm_buffer_pool_capacity_bytes{pool="direct"} 8192.0 031 * jvm_buffer_pool_capacity_bytes{pool="mapped"} 0.0 032 * # HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool. 033 * # TYPE jvm_buffer_pool_used_buffers gauge 034 * jvm_buffer_pool_used_buffers{pool="direct"} 1.0 035 * jvm_buffer_pool_used_buffers{pool="mapped"} 0.0 036 * # HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool. 037 * # TYPE jvm_buffer_pool_used_bytes gauge 038 * jvm_buffer_pool_used_bytes{pool="direct"} 8192.0 039 * jvm_buffer_pool_used_bytes{pool="mapped"} 0.0 040 * </pre> 041 */ 042public class JvmBufferPoolMetrics { 043 044 private static final String JVM_BUFFER_POOL_USED_BYTES = "jvm_buffer_pool_used_bytes"; 045 private static final String JVM_BUFFER_POOL_CAPACITY_BYTES = "jvm_buffer_pool_capacity_bytes"; 046 private static final String JVM_BUFFER_POOL_USED_BUFFERS = "jvm_buffer_pool_used_buffers"; 047 048 private final PrometheusProperties config; 049 private final List<BufferPoolMXBean> bufferPoolBeans; 050 051 private JvmBufferPoolMetrics( 052 List<BufferPoolMXBean> bufferPoolBeans, PrometheusProperties config) { 053 this.config = config; 054 this.bufferPoolBeans = bufferPoolBeans; 055 } 056 057 private void register(PrometheusRegistry registry) { 058 059 GaugeWithCallback.builder(config) 060 .name(JVM_BUFFER_POOL_USED_BYTES) 061 .help("Used bytes of a given JVM buffer pool.") 062 .unit(Unit.BYTES) 063 .labelNames("pool") 064 .callback( 065 callback -> { 066 for (BufferPoolMXBean pool : bufferPoolBeans) { 067 callback.call(pool.getMemoryUsed(), pool.getName()); 068 } 069 }) 070 .register(registry); 071 072 GaugeWithCallback.builder(config) 073 .name(JVM_BUFFER_POOL_CAPACITY_BYTES) 074 .help("Bytes capacity of a given JVM buffer pool.") 075 .unit(Unit.BYTES) 076 .labelNames("pool") 077 .callback( 078 callback -> { 079 for (BufferPoolMXBean pool : bufferPoolBeans) { 080 callback.call(pool.getTotalCapacity(), pool.getName()); 081 } 082 }) 083 .register(registry); 084 085 GaugeWithCallback.builder(config) 086 .name(JVM_BUFFER_POOL_USED_BUFFERS) 087 .help("Used buffers of a given JVM buffer pool.") 088 .labelNames("pool") 089 .callback( 090 callback -> { 091 for (BufferPoolMXBean pool : bufferPoolBeans) { 092 callback.call(pool.getCount(), pool.getName()); 093 } 094 }) 095 .register(registry); 096 } 097 098 public static Builder builder() { 099 return new Builder(PrometheusProperties.get()); 100 } 101 102 public static Builder builder(PrometheusProperties config) { 103 return new Builder(config); 104 } 105 106 public static class Builder { 107 108 private final PrometheusProperties config; 109 private List<BufferPoolMXBean> bufferPoolBeans; 110 111 private Builder(PrometheusProperties config) { 112 this.config = config; 113 } 114 115 /** Package private. For testing only. */ 116 Builder bufferPoolBeans(List<BufferPoolMXBean> bufferPoolBeans) { 117 this.bufferPoolBeans = bufferPoolBeans; 118 return this; 119 } 120 121 public void register() { 122 register(PrometheusRegistry.defaultRegistry); 123 } 124 125 public void register(PrometheusRegistry registry) { 126 List<BufferPoolMXBean> bufferPoolBeans = this.bufferPoolBeans; 127 if (bufferPoolBeans == null) { 128 bufferPoolBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); 129 } 130 new JvmBufferPoolMetrics(bufferPoolBeans, config).register(registry); 131 } 132 } 133}