13
13
import io .prometheus .metrics .model .registry .PrometheusRegistry ;
14
14
import io .prometheus .metrics .model .snapshots .CounterSnapshot ;
15
15
import io .prometheus .metrics .model .snapshots .DataPointSnapshot ;
16
+ import io .prometheus .metrics .model .snapshots .GaugeSnapshot ;
16
17
import io .prometheus .metrics .model .snapshots .Labels ;
17
18
import io .prometheus .metrics .model .snapshots .MetricSnapshots ;
18
19
import io .prometheus .metrics .model .snapshots .SummarySnapshot ;
22
23
import java .nio .charset .StandardCharsets ;
23
24
import java .util .List ;
24
25
import org .junit .jupiter .api .Test ;
26
+ import org .junit .jupiter .params .ParameterizedTest ;
27
+ import org .junit .jupiter .params .provider .EnumSource ;
25
28
26
29
@ SuppressWarnings ("CheckReturnValue" )
27
30
class CacheMetricsCollectorTest {
31
+ // This enum was added to simplify test parametrization on argument options.
32
+ public enum Options {
33
+ LEGACY (false , false ),
34
+ COLLECT_EVICTION_WEIGHT_AS_COUNTER (true , false ),
35
+ COLLECT_WEIGHTED_SIZE (false , true ),
36
+ BUILDER_DEFAULT (true , true );
37
+
38
+ private final boolean collectEvictionWeightAsCounter ;
39
+ private final boolean collectWeightedSize ;
40
+
41
+ Options (boolean collectEvictionWeightAsCounter , boolean collectWeightedSize ) {
42
+ this .collectEvictionWeightAsCounter = collectEvictionWeightAsCounter ;
43
+ this .collectWeightedSize = collectWeightedSize ;
44
+ }
45
+ }
28
46
29
- @ Test
30
- public void cacheExposesMetricsForHitMissAndEviction () {
47
+ @ ParameterizedTest
48
+ @ EnumSource
49
+ public void cacheExposesMetricsForHitMissAndEviction (Options options ) {
31
50
// Run cleanup in same thread, to remove async behavior with evictions
32
51
final Cache <String , String > cache =
33
52
Caffeine .newBuilder ().maximumSize (2 ).recordStats ().executor (Runnable ::run ).build ();
34
53
35
- final CacheMetricsCollector collector = new CacheMetricsCollector ();
54
+ final CacheMetricsCollector collector =
55
+ CacheMetricsCollector .builder ()
56
+ .collectEvictionWeightAsCounter (options .collectEvictionWeightAsCounter )
57
+ .collectWeightedSize (options .collectWeightedSize )
58
+ .build ();
59
+ collector .addCache ("users" , cache );
60
+
61
+ final PrometheusRegistry registry = new PrometheusRegistry ();
62
+ registry .register (collector );
63
+
64
+ cache .getIfPresent ("user1" );
65
+ cache .getIfPresent ("user1" );
66
+ cache .put ("user1" , "First User" );
67
+ cache .getIfPresent ("user1" );
68
+
69
+ // Add to cache to trigger eviction.
70
+ cache .put ("user2" , "Second User" );
71
+ cache .put ("user3" , "Third User" );
72
+ cache .put ("user4" , "Fourth User" );
73
+
74
+ assertCounterMetric (registry , "caffeine_cache_hit" , "users" , 1.0 );
75
+ assertCounterMetric (registry , "caffeine_cache_miss" , "users" , 2.0 );
76
+ assertCounterMetric (registry , "caffeine_cache_requests" , "users" , 3.0 );
77
+ assertCounterMetric (registry , "caffeine_cache_eviction" , "users" , 2.0 );
78
+ String openMetricEvictionWeightExpectedText ;
79
+ if (options .collectEvictionWeightAsCounter ) {
80
+ assertCounterMetric (registry , "caffeine_cache_eviction_weight" , "users" , 2.0 );
81
+ openMetricEvictionWeightExpectedText =
82
+ "# TYPE caffeine_cache_eviction_weight counter\n "
83
+ + "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n "
84
+ + "caffeine_cache_eviction_weight_total{cache=\" users\" } 2.0\n " ;
85
+ } else {
86
+ assertGaugeMetric (registry , "caffeine_cache_eviction_weight" , "users" , 2.0 );
87
+ openMetricEvictionWeightExpectedText =
88
+ "# TYPE caffeine_cache_eviction_weight gauge\n "
89
+ + "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n "
90
+ + "caffeine_cache_eviction_weight{cache=\" users\" } 2.0\n " ;
91
+ }
92
+
93
+ final String expected =
94
+ "# TYPE caffeine_cache_estimated_size gauge\n "
95
+ + "# HELP caffeine_cache_estimated_size Estimated cache size\n "
96
+ + "caffeine_cache_estimated_size{cache=\" users\" } 2.0\n "
97
+ + "# TYPE caffeine_cache_eviction counter\n "
98
+ + "# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries\n "
99
+ + "caffeine_cache_eviction_total{cache=\" users\" } 2.0\n "
100
+ + openMetricEvictionWeightExpectedText
101
+ + "# TYPE caffeine_cache_hit counter\n "
102
+ + "# HELP caffeine_cache_hit Cache hit totals\n "
103
+ + "caffeine_cache_hit_total{cache=\" users\" } 1.0\n "
104
+ + "# TYPE caffeine_cache_miss counter\n "
105
+ + "# HELP caffeine_cache_miss Cache miss totals\n "
106
+ + "caffeine_cache_miss_total{cache=\" users\" } 2.0\n "
107
+ + "# TYPE caffeine_cache_requests counter\n "
108
+ + "# HELP caffeine_cache_requests Cache request totals, hits + misses\n "
109
+ + "caffeine_cache_requests_total{cache=\" users\" } 3.0\n "
110
+ + "# EOF\n " ;
111
+
112
+ assertThat (convertToOpenMetricsFormat (registry )).isEqualTo (expected );
113
+ }
114
+
115
+ @ ParameterizedTest
116
+ @ EnumSource
117
+ public void weightedCacheExposesMetricsForHitMissAndEvictionWeightedSize (Options options ) {
118
+ // Run cleanup in same thread, to remove async behavior with evictions
119
+ final Cache <String , String > cache =
120
+ Caffeine .newBuilder ()
121
+ .weigher ((String k , String v ) -> k .length () + v .length ())
122
+ .maximumWeight (35 )
123
+ .recordStats ()
124
+ .executor (Runnable ::run )
125
+ .build ();
126
+
127
+ final CacheMetricsCollector collector =
128
+ CacheMetricsCollector .builder ()
129
+ .collectEvictionWeightAsCounter (options .collectEvictionWeightAsCounter )
130
+ .collectWeightedSize (options .collectWeightedSize )
131
+ .build ();
36
132
collector .addCache ("users" , cache );
37
133
38
134
final PrometheusRegistry registry = new PrometheusRegistry ();
@@ -52,6 +148,29 @@ public void cacheExposesMetricsForHitMissAndEviction() {
52
148
assertCounterMetric (registry , "caffeine_cache_miss" , "users" , 2.0 );
53
149
assertCounterMetric (registry , "caffeine_cache_requests" , "users" , 3.0 );
54
150
assertCounterMetric (registry , "caffeine_cache_eviction" , "users" , 2.0 );
151
+ String openMetricEvictionWeightExpectedText ;
152
+ if (options .collectEvictionWeightAsCounter ) {
153
+ assertCounterMetric (registry , "caffeine_cache_eviction_weight" , "users" , 31.0 );
154
+ openMetricEvictionWeightExpectedText =
155
+ "# TYPE caffeine_cache_eviction_weight counter\n "
156
+ + "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n "
157
+ + "caffeine_cache_eviction_weight_total{cache=\" users\" } 31.0\n " ;
158
+ } else {
159
+ assertGaugeMetric (registry , "caffeine_cache_eviction_weight" , "users" , 31.0 );
160
+ openMetricEvictionWeightExpectedText =
161
+ "# TYPE caffeine_cache_eviction_weight gauge\n "
162
+ + "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n "
163
+ + "caffeine_cache_eviction_weight{cache=\" users\" } 31.0\n " ;
164
+ }
165
+ String openMetricWeightedSizeExpectedText ;
166
+ if (options .collectWeightedSize ) {
167
+ openMetricWeightedSizeExpectedText =
168
+ "# TYPE caffeine_cache_weighted_size gauge\n "
169
+ + "# HELP caffeine_cache_weighted_size Approximate accumulated weight of cache entries\n "
170
+ + "caffeine_cache_weighted_size{cache=\" users\" } 31.0\n " ;
171
+ } else {
172
+ openMetricWeightedSizeExpectedText = "" ;
173
+ }
55
174
56
175
final String expected =
57
176
"# TYPE caffeine_cache_estimated_size gauge\n "
@@ -60,9 +179,7 @@ public void cacheExposesMetricsForHitMissAndEviction() {
60
179
+ "# TYPE caffeine_cache_eviction counter\n "
61
180
+ "# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries\n "
62
181
+ "caffeine_cache_eviction_total{cache=\" users\" } 2.0\n "
63
- + "# TYPE caffeine_cache_eviction_weight gauge\n "
64
- + "# HELP caffeine_cache_eviction_weight Cache eviction weight\n "
65
- + "caffeine_cache_eviction_weight{cache=\" users\" } 2.0\n "
182
+ + openMetricEvictionWeightExpectedText
66
183
+ "# TYPE caffeine_cache_hit counter\n "
67
184
+ "# HELP caffeine_cache_hit Cache hit totals\n "
68
185
+ "caffeine_cache_hit_total{cache=\" users\" } 1.0\n "
@@ -72,6 +189,7 @@ public void cacheExposesMetricsForHitMissAndEviction() {
72
189
+ "# TYPE caffeine_cache_requests counter\n "
73
190
+ "# HELP caffeine_cache_requests Cache request totals, hits + misses\n "
74
191
+ "caffeine_cache_requests_total{cache=\" users\" } 3.0\n "
192
+ + openMetricWeightedSizeExpectedText
75
193
+ "# EOF\n " ;
76
194
77
195
assertThat (convertToOpenMetricsFormat (registry )).isEqualTo (expected );
@@ -87,7 +205,7 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception {
87
205
.thenReturn ("Third User" );
88
206
89
207
final LoadingCache <String , String > cache = Caffeine .newBuilder ().recordStats ().build (loader );
90
- final CacheMetricsCollector collector = new CacheMetricsCollector ();
208
+ final CacheMetricsCollector collector = CacheMetricsCollector . builder (). build ();
91
209
92
210
collector .addCache ("loadingusers" , cache );
93
211
@@ -117,9 +235,14 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception {
117
235
assertThat (loadDuration .getSum ()).isGreaterThan (0 );
118
236
}
119
237
120
- @ Test
121
- public void getPrometheusNamesHasSameSizeAsMetricSizeWhenScraping () {
122
- final CacheMetricsCollector collector = new CacheMetricsCollector ();
238
+ @ ParameterizedTest
239
+ @ EnumSource
240
+ public void getPrometheusNamesHasSameSizeAsMetricSizeWhenScraping (Options options ) {
241
+ final CacheMetricsCollector collector =
242
+ CacheMetricsCollector .builder ()
243
+ .collectEvictionWeightAsCounter (options .collectEvictionWeightAsCounter )
244
+ .collectWeightedSize (options .collectWeightedSize )
245
+ .build ();
123
246
124
247
final PrometheusRegistry registry = new PrometheusRegistry ();
125
248
registry .register (collector );
@@ -130,9 +253,14 @@ public void getPrometheusNamesHasSameSizeAsMetricSizeWhenScraping() {
130
253
assertThat (prometheusNames ).hasSize (metricSnapshots .size ());
131
254
}
132
255
133
- @ Test
134
- public void collectedMetricNamesAreKnownPrometheusNames () {
135
- final CacheMetricsCollector collector = new CacheMetricsCollector ();
256
+ @ ParameterizedTest
257
+ @ EnumSource
258
+ public void collectedMetricNamesAreKnownPrometheusNames (Options options ) {
259
+ final CacheMetricsCollector collector =
260
+ CacheMetricsCollector .builder ()
261
+ .collectEvictionWeightAsCounter (options .collectEvictionWeightAsCounter )
262
+ .collectWeightedSize (options .collectWeightedSize )
263
+ .build ();
136
264
137
265
final PrometheusRegistry registry = new PrometheusRegistry ();
138
266
registry .register (collector );
@@ -153,6 +281,14 @@ private void assertCounterMetric(
153
281
assertThat (dataPointSnapshot .getValue ()).isEqualTo (value );
154
282
}
155
283
284
+ private void assertGaugeMetric (
285
+ PrometheusRegistry registry , String name , String cacheName , double value ) {
286
+ final GaugeSnapshot .GaugeDataPointSnapshot dataPointSnapshot =
287
+ (GaugeSnapshot .GaugeDataPointSnapshot ) getDataPointSnapshot (registry , name , cacheName );
288
+
289
+ assertThat (dataPointSnapshot .getValue ()).isEqualTo (value );
290
+ }
291
+
156
292
private DataPointSnapshot getDataPointSnapshot (
157
293
PrometheusRegistry registry , String name , String cacheName ) {
158
294
final Labels labels = Labels .of (new String [] {"cache" }, new String [] {cacheName });
0 commit comments