001package io.prometheus.metrics.core.metrics; 002 003import io.prometheus.metrics.config.PrometheusProperties; 004import io.prometheus.metrics.model.snapshots.GaugeSnapshot; 005 006import java.util.ArrayList; 007import java.util.Collections; 008import java.util.List; 009import java.util.function.Consumer; 010 011/** 012 * Example: 013 * <pre>{@code 014 * MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); 015 * 016 * GaugeWithCallback.builder() 017 * .name("jvm_memory_bytes_used") 018 * .help("Used bytes of a given JVM memory area.") 019 * .unit(Unit.BYTES) 020 * .labelNames("area") 021 * .callback(callback -> { 022 * callback.call(memoryBean.getHeapMemoryUsage().getUsed(), "heap"); 023 * callback.call(memoryBean.getNonHeapMemoryUsage().getUsed(), "nonheap"); 024 * }) 025 * .register(); 026 * }</pre> 027 */ 028public class GaugeWithCallback extends CallbackMetric { 029 030 @FunctionalInterface 031 public interface Callback { 032 void call(double value, String... labelValues); 033 } 034 035 private final Consumer<Callback> callback; 036 037 private GaugeWithCallback(Builder builder) { 038 super(builder); 039 this.callback = builder.callback; 040 if (callback == null) { 041 throw new IllegalArgumentException("callback cannot be null"); 042 } 043 } 044 045 @Override 046 public GaugeSnapshot collect() { 047 List<GaugeSnapshot.GaugeDataPointSnapshot> dataPoints = new ArrayList<>(); 048 callback.accept((value, labelValues) -> { 049 dataPoints.add(new GaugeSnapshot.GaugeDataPointSnapshot(value, makeLabels(labelValues), null, 0L)); 050 }); 051 return new GaugeSnapshot(getMetadata(), dataPoints); 052 } 053 054 public static Builder builder() { 055 return new Builder(PrometheusProperties.get()); 056 } 057 058 public static Builder builder(PrometheusProperties properties) { 059 return new Builder(properties); 060 } 061 062 public static class Builder extends CallbackMetric.Builder<GaugeWithCallback.Builder, GaugeWithCallback> { 063 064 private Consumer<Callback> callback; 065 066 public Builder callback(Consumer<Callback> callback) { 067 this.callback = callback; 068 return self(); 069 } 070 071 private Builder(PrometheusProperties properties) { 072 super(Collections.emptyList(), properties); 073 } 074 075 @Override 076 public GaugeWithCallback build() { 077 return new GaugeWithCallback(this); 078 } 079 080 @Override 081 protected Builder self() { 082 return this; 083 } 084 } 085}