33import com .github .benmanes .caffeine .cache .AsyncCache ;
44import com .github .benmanes .caffeine .cache .Cache ;
55import com .github .benmanes .caffeine .cache .LoadingCache ;
6+ import com .github .benmanes .caffeine .cache .Policy ;
67import com .github .benmanes .caffeine .cache .stats .CacheStats ;
78import io .prometheus .metrics .model .registry .MultiCollector ;
89import io .prometheus .metrics .model .snapshots .CounterSnapshot ;
1415import java .util .Collections ;
1516import java .util .List ;
1617import java .util .Map ;
18+ import java .util .Optional ;
1719import java .util .concurrent .ConcurrentHashMap ;
1820import java .util .concurrent .ConcurrentMap ;
21+ import java .util .stream .Collectors ;
1922
2023/**
2124 * Collect metrics from Caffeine's com.github.benmanes.caffeine.cache.Cache.
2528 * <pre>{@code
2629 * // Note that `recordStats()` is required to gather non-zero statistics
2730 * Cache<String, String> cache = Caffeine.newBuilder().recordStats().build();
28- * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector();
31+ * CacheMetricsCollector cacheMetrics = CacheMetricsCollector.builder().build ();
2932 * PrometheusRegistry.defaultRegistry.register(cacheMetrics);
3033 * cacheMetrics.addCache("mycache", cache);
3134 *
@@ -63,6 +66,7 @@ public class CacheMetricsCollector implements MultiCollector {
6366 private static final String METRIC_NAME_CACHE_LOAD_FAILURE = "caffeine_cache_load_failure" ;
6467 private static final String METRIC_NAME_CACHE_LOADS = "caffeine_cache_loads" ;
6568 private static final String METRIC_NAME_CACHE_ESTIMATED_SIZE = "caffeine_cache_estimated_size" ;
69+ private static final String METRIC_NAME_CACHE_WEIGHTED_SIZE = "caffeine_cache_weighted_size" ;
6670 private static final String METRIC_NAME_CACHE_LOAD_DURATION_SECONDS =
6771 "caffeine_cache_load_duration_seconds" ;
6872
@@ -77,9 +81,38 @@ public class CacheMetricsCollector implements MultiCollector {
7781 METRIC_NAME_CACHE_LOAD_FAILURE ,
7882 METRIC_NAME_CACHE_LOADS ,
7983 METRIC_NAME_CACHE_ESTIMATED_SIZE ,
84+ METRIC_NAME_CACHE_WEIGHTED_SIZE ,
8085 METRIC_NAME_CACHE_LOAD_DURATION_SECONDS ));
8186
8287 protected final ConcurrentMap <String , Cache <?, ?>> children = new ConcurrentHashMap <>();
88+ private final boolean collectEvictionWeightAsCounter ;
89+ private final boolean collectWeightedSize ;
90+
91+ /**
92+ * Instantiates a {@link CacheMetricsCollector}, with the legacy parameters.
93+ *
94+ * <p>The use of this constructor is discouraged, in favor of a Builder pattern {@link #builder()}
95+ *
96+ * <p>Note that the {@link #builder()} API has different default values than this deprecated
97+ * constructor.
98+ */
99+ @ Deprecated
100+ public CacheMetricsCollector () {
101+ this (false , false );
102+ }
103+
104+ /**
105+ * Instantiate a {@link CacheMetricsCollector}
106+ *
107+ * @param collectEvictionWeightAsCounter If true, {@code caffeine_cache_eviction_weight} will be
108+ * observed as an incrementing counter instead of a gauge.
109+ * @param collectWeightedSize If true, {@code caffeine_cache_weighted_size} will be observed.
110+ */
111+ protected CacheMetricsCollector (
112+ boolean collectEvictionWeightAsCounter , boolean collectWeightedSize ) {
113+ this .collectEvictionWeightAsCounter = collectEvictionWeightAsCounter ;
114+ this .collectWeightedSize = collectWeightedSize ;
115+ }
83116
84117 /**
85118 * Add or replace the cache with the given name.
@@ -146,10 +179,14 @@ public MetricSnapshots collect() {
146179 .name (METRIC_NAME_CACHE_EVICTION )
147180 .help ("Cache eviction totals, doesn't include manually removed entries" );
148181
149- final GaugeSnapshot .Builder cacheEvictionWeight =
182+ final CounterSnapshot .Builder cacheEvictionWeight =
183+ CounterSnapshot .builder ()
184+ .name (METRIC_NAME_CACHE_EVICTION_WEIGHT )
185+ .help ("Weight of evicted cache entries, doesn't include manually removed entries" );
186+ final GaugeSnapshot .Builder cacheEvictionWeightLegacyGauge =
150187 GaugeSnapshot .builder ()
151188 .name (METRIC_NAME_CACHE_EVICTION_WEIGHT )
152- .help ("Cache eviction weight " );
189+ .help ("Weight of evicted cache entries, doesn't include manually removed entries " );
153190
154191 final CounterSnapshot .Builder cacheLoadFailure =
155192 CounterSnapshot .builder ().name (METRIC_NAME_CACHE_LOAD_FAILURE ).help ("Cache load failures" );
@@ -162,6 +199,11 @@ public MetricSnapshots collect() {
162199 final GaugeSnapshot .Builder cacheSize =
163200 GaugeSnapshot .builder ().name (METRIC_NAME_CACHE_ESTIMATED_SIZE ).help ("Estimated cache size" );
164201
202+ final GaugeSnapshot .Builder cacheWeightedSize =
203+ GaugeSnapshot .builder ()
204+ .name (METRIC_NAME_CACHE_WEIGHTED_SIZE )
205+ .help ("Approximate accumulated weight of cache entries" );
206+
165207 final SummarySnapshot .Builder cacheLoadSummary =
166208 SummarySnapshot .builder ()
167209 .name (METRIC_NAME_CACHE_LOAD_DURATION_SECONDS )
@@ -175,6 +217,11 @@ public MetricSnapshots collect() {
175217
176218 try {
177219 cacheEvictionWeight .dataPoint (
220+ CounterSnapshot .CounterDataPointSnapshot .builder ()
221+ .labels (labels )
222+ .value (stats .evictionWeight ())
223+ .build ());
224+ cacheEvictionWeightLegacyGauge .dataPoint (
178225 GaugeSnapshot .GaugeDataPointSnapshot .builder ()
179226 .labels (labels )
180227 .value (stats .evictionWeight ())
@@ -183,6 +230,17 @@ public MetricSnapshots collect() {
183230 // EvictionWeight metric is unavailable, newer version of Caffeine is needed.
184231 }
185232
233+ if (collectWeightedSize ) {
234+ final Optional <? extends Policy .Eviction <?, ?>> eviction = c .getValue ().policy ().eviction ();
235+ if (eviction .isPresent () && eviction .get ().weightedSize ().isPresent ()) {
236+ cacheWeightedSize .dataPoint (
237+ GaugeSnapshot .GaugeDataPointSnapshot .builder ()
238+ .labels (labels )
239+ .value (eviction .get ().weightedSize ().getAsLong ())
240+ .build ());
241+ }
242+ }
243+
186244 cacheHitTotal .dataPoint (
187245 CounterSnapshot .CounterDataPointSnapshot .builder ()
188246 .labels (labels )
@@ -235,12 +293,19 @@ public MetricSnapshots collect() {
235293 }
236294 }
237295
296+ if (collectWeightedSize ) {
297+ metricSnapshotsBuilder .metricSnapshot (cacheWeightedSize .build ());
298+ }
299+
238300 return metricSnapshotsBuilder
239301 .metricSnapshot (cacheHitTotal .build ())
240302 .metricSnapshot (cacheMissTotal .build ())
241303 .metricSnapshot (cacheRequestsTotal .build ())
242304 .metricSnapshot (cacheEvictionTotal .build ())
243- .metricSnapshot (cacheEvictionWeight .build ())
305+ .metricSnapshot (
306+ collectEvictionWeightAsCounter
307+ ? cacheEvictionWeight .build ()
308+ : cacheEvictionWeightLegacyGauge .build ())
244309 .metricSnapshot (cacheLoadFailure .build ())
245310 .metricSnapshot (cacheLoadTotal .build ())
246311 .metricSnapshot (cacheSize .build ())
@@ -250,6 +315,35 @@ public MetricSnapshots collect() {
250315
251316 @ Override
252317 public List <String > getPrometheusNames () {
318+ if (!collectWeightedSize ) {
319+ return ALL_METRIC_NAMES .stream ()
320+ .filter (s -> !METRIC_NAME_CACHE_WEIGHTED_SIZE .equals (s ))
321+ .collect (Collectors .toList ());
322+ }
253323 return ALL_METRIC_NAMES ;
254324 }
325+
326+ public static Builder builder () {
327+ return new Builder ();
328+ }
329+
330+ public static class Builder {
331+
332+ private boolean collectEvictionWeightAsCounter = true ;
333+ private boolean collectWeightedSize = true ;
334+
335+ public Builder collectEvictionWeightAsCounter (boolean collectEvictionWeightAsCounter ) {
336+ this .collectEvictionWeightAsCounter = collectEvictionWeightAsCounter ;
337+ return this ;
338+ }
339+
340+ public Builder collectWeightedSize (boolean collectWeightedSize ) {
341+ this .collectWeightedSize = collectWeightedSize ;
342+ return this ;
343+ }
344+
345+ public CacheMetricsCollector build () {
346+ return new CacheMetricsCollector (collectEvictionWeightAsCounter , collectWeightedSize );
347+ }
348+ }
255349}
0 commit comments