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