Skip to content

Commit 3fb7e1e

Browse files
committed
Add caffeine_cache_weighted_size gauge metric to caffeine-instrumentation
Signed-off-by: Jean Hominal <[email protected]>
1 parent af89825 commit 3fb7e1e

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java

+19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.github.benmanes.caffeine.cache.AsyncCache;
44
import com.github.benmanes.caffeine.cache.Cache;
55
import com.github.benmanes.caffeine.cache.LoadingCache;
6+
import com.github.benmanes.caffeine.cache.Policy;
67
import com.github.benmanes.caffeine.cache.stats.CacheStats;
78
import io.prometheus.metrics.model.registry.MultiCollector;
89
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
@@ -14,6 +15,7 @@
1415
import java.util.Collections;
1516
import java.util.List;
1617
import java.util.Map;
18+
import java.util.Optional;
1719
import java.util.concurrent.ConcurrentHashMap;
1820
import java.util.concurrent.ConcurrentMap;
1921

@@ -63,6 +65,7 @@ public class CacheMetricsCollector implements MultiCollector {
6365
private static final String METRIC_NAME_CACHE_LOAD_FAILURE = "caffeine_cache_load_failure";
6466
private static final String METRIC_NAME_CACHE_LOADS = "caffeine_cache_loads";
6567
private static final String METRIC_NAME_CACHE_ESTIMATED_SIZE = "caffeine_cache_estimated_size";
68+
private static final String METRIC_NAME_CACHE_WEIGHTED_SIZE = "caffeine_cache_weighted_size";
6669
private static final String METRIC_NAME_CACHE_LOAD_DURATION_SECONDS =
6770
"caffeine_cache_load_duration_seconds";
6871

@@ -77,6 +80,7 @@ public class CacheMetricsCollector implements MultiCollector {
7780
METRIC_NAME_CACHE_LOAD_FAILURE,
7881
METRIC_NAME_CACHE_LOADS,
7982
METRIC_NAME_CACHE_ESTIMATED_SIZE,
83+
METRIC_NAME_CACHE_WEIGHTED_SIZE,
8084
METRIC_NAME_CACHE_LOAD_DURATION_SECONDS));
8185

8286
protected final ConcurrentMap<String, Cache<?, ?>> children = new ConcurrentHashMap<>();
@@ -162,6 +166,11 @@ public MetricSnapshots collect() {
162166
final GaugeSnapshot.Builder cacheSize =
163167
GaugeSnapshot.builder().name(METRIC_NAME_CACHE_ESTIMATED_SIZE).help("Estimated cache size");
164168

169+
final GaugeSnapshot.Builder cacheWeightedSize =
170+
GaugeSnapshot.builder()
171+
.name(METRIC_NAME_CACHE_WEIGHTED_SIZE)
172+
.help("Approximate accumulated weight of cache entries");
173+
165174
final SummarySnapshot.Builder cacheLoadSummary =
166175
SummarySnapshot.builder()
167176
.name(METRIC_NAME_CACHE_LOAD_DURATION_SECONDS)
@@ -183,6 +192,15 @@ public MetricSnapshots collect() {
183192
// EvictionWeight metric is unavailable, newer version of Caffeine is needed.
184193
}
185194

195+
final Optional<? extends Policy.Eviction<?, ?>> eviction = c.getValue().policy().eviction();
196+
if (eviction.isPresent() && eviction.get().weightedSize().isPresent()) {
197+
cacheWeightedSize.dataPoint(
198+
GaugeSnapshot.GaugeDataPointSnapshot.builder()
199+
.labels(labels)
200+
.value(eviction.get().weightedSize().getAsLong())
201+
.build());
202+
}
203+
186204
cacheHitTotal.dataPoint(
187205
CounterSnapshot.CounterDataPointSnapshot.builder()
188206
.labels(labels)
@@ -244,6 +262,7 @@ public MetricSnapshots collect() {
244262
.metricSnapshot(cacheLoadFailure.build())
245263
.metricSnapshot(cacheLoadTotal.build())
246264
.metricSnapshot(cacheSize.build())
265+
.metricSnapshot(cacheWeightedSize.build())
247266
.metricSnapshot(cacheLoadSummary.build())
248267
.build();
249268
}

prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java

+60
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,66 @@ public void cacheExposesMetricsForHitMissAndEviction() {
7878
assertThat(convertToOpenMetricsFormat(registry)).isEqualTo(expected);
7979
}
8080

81+
@Test
82+
public void cacheExposesMetricsForHitMissAndEvictionForWeightedCache() {
83+
// Run cleanup in same thread, to remove async behavior with evictions
84+
final Cache<String, String> cache =
85+
Caffeine.newBuilder()
86+
.weigher((String k, String v) -> k.length() + v.length())
87+
.maximumWeight(35)
88+
.recordStats()
89+
.executor(Runnable::run)
90+
.build();
91+
92+
final CacheMetricsCollector collector = new CacheMetricsCollector();
93+
collector.addCache("users", cache);
94+
95+
final PrometheusRegistry registry = new PrometheusRegistry();
96+
registry.register(collector);
97+
98+
cache.getIfPresent("user1");
99+
cache.getIfPresent("user1");
100+
cache.put("user1", "First User");
101+
cache.getIfPresent("user1");
102+
103+
// Add to cache to trigger eviction.
104+
cache.put("user2", "Second User");
105+
cache.put("user3", "Third User");
106+
cache.put("user4", "Fourth User");
107+
108+
assertCounterMetric(registry, "caffeine_cache_hit", "users", 1.0);
109+
assertCounterMetric(registry, "caffeine_cache_miss", "users", 2.0);
110+
assertCounterMetric(registry, "caffeine_cache_requests", "users", 3.0);
111+
assertCounterMetric(registry, "caffeine_cache_eviction", "users", 2.0);
112+
assertCounterMetric(registry, "caffeine_cache_eviction_weight", "users", 31.0);
113+
114+
final String expected =
115+
"# TYPE caffeine_cache_estimated_size gauge\n"
116+
+ "# HELP caffeine_cache_estimated_size Estimated cache size\n"
117+
+ "caffeine_cache_estimated_size{cache=\"users\"} 2.0\n"
118+
+ "# TYPE caffeine_cache_eviction counter\n"
119+
+ "# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries\n"
120+
+ "caffeine_cache_eviction_total{cache=\"users\"} 2.0\n"
121+
+ "# TYPE caffeine_cache_eviction_weight counter\n"
122+
+ "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n"
123+
+ "caffeine_cache_eviction_weight_total{cache=\"users\"} 31.0\n"
124+
+ "# TYPE caffeine_cache_hit counter\n"
125+
+ "# HELP caffeine_cache_hit Cache hit totals\n"
126+
+ "caffeine_cache_hit_total{cache=\"users\"} 1.0\n"
127+
+ "# TYPE caffeine_cache_miss counter\n"
128+
+ "# HELP caffeine_cache_miss Cache miss totals\n"
129+
+ "caffeine_cache_miss_total{cache=\"users\"} 2.0\n"
130+
+ "# TYPE caffeine_cache_requests counter\n"
131+
+ "# HELP caffeine_cache_requests Cache request totals, hits + misses\n"
132+
+ "caffeine_cache_requests_total{cache=\"users\"} 3.0\n"
133+
+ "# TYPE caffeine_cache_weighted_size gauge\n"
134+
+ "# HELP caffeine_cache_weighted_size Approximate accumulated weight of cache entries\n"
135+
+ "caffeine_cache_weighted_size{cache=\"users\"} 31.0\n"
136+
+ "# EOF\n";
137+
138+
assertThat(convertToOpenMetricsFormat(registry)).isEqualTo(expected);
139+
}
140+
81141
@SuppressWarnings("unchecked")
82142
@Test
83143
public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception {

0 commit comments

Comments
 (0)