001package io.prometheus.metrics.core.metrics; 002 003import io.prometheus.metrics.config.PrometheusProperties; 004import io.prometheus.metrics.model.snapshots.Exemplars; 005import io.prometheus.metrics.model.snapshots.Quantiles; 006import io.prometheus.metrics.model.snapshots.SummarySnapshot; 007 008import java.util.ArrayList; 009import java.util.Collections; 010import java.util.List; 011import java.util.function.Consumer; 012 013/** 014 * Example: 015 * <pre>{@code 016 * double MILLISECONDS_PER_SECOND = 1E3; 017 * 018 * SummaryWithCallback.builder() 019 * .name("jvm_gc_collection_seconds") 020 * .help("Time spent in a given JVM garbage collector in seconds.") 021 * .unit(Unit.SECONDS) 022 * .labelNames("gc") 023 * .callback(callback -> { 024 * for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) { 025 * callback.call( 026 * gc.getCollectionCount(), 027 * gc.getCollectionTime() / MILLISECONDS_PER_SECOND, 028 * Quantiles.EMPTY, 029 * gc.getName() 030 * ); 031 * } 032 * }) 033 * .register(); 034 * }</pre> 035 */ 036public class SummaryWithCallback extends CallbackMetric { 037 038 @FunctionalInterface 039 public interface Callback { 040 void call(long count, double sum, Quantiles quantiles, String... labelValues); 041 } 042 043 private final Consumer<Callback> callback; 044 045 private SummaryWithCallback(Builder builder) { 046 super(builder); 047 this.callback = builder.callback; 048 if (callback == null) { 049 throw new IllegalArgumentException("callback cannot be null"); 050 } 051 } 052 053 @Override 054 public SummarySnapshot collect() { 055 List<SummarySnapshot.SummaryDataPointSnapshot> dataPoints = new ArrayList<>(); 056 callback.accept((count, sum, quantiles, labelValues) -> { 057 dataPoints.add(new SummarySnapshot.SummaryDataPointSnapshot(count, sum, quantiles, makeLabels(labelValues), Exemplars.EMPTY, 0L)); 058 }); 059 return new SummarySnapshot(getMetadata(), dataPoints); 060 } 061 062 public static Builder builder() { 063 return new Builder(PrometheusProperties.get()); 064 } 065 066 public static Builder builder(PrometheusProperties properties) { 067 return new Builder(properties); 068 } 069 070 public static class Builder extends CallbackMetric.Builder<SummaryWithCallback.Builder, SummaryWithCallback> { 071 072 private Consumer<Callback> callback; 073 074 public Builder callback(Consumer<Callback> callback) { 075 this.callback = callback; 076 return self(); 077 } 078 079 private Builder(PrometheusProperties properties) { 080 super(Collections.singletonList("quantile"), properties); 081 } 082 083 @Override 084 public SummaryWithCallback build() { 085 return new SummaryWithCallback(this); 086 } 087 088 @Override 089 protected Builder self() { 090 return this; 091 } 092 } 093}