Skip to content

Commit 3be16d9

Browse files
Apoorv JainApoorv Jain
andauthored
ENG 5066: GuavaCacheMetric Support (#32)
* ENG-5066: GuavaCache Metrics Support * ENG 5066: GuavaCache Metric Support * ENG-5066, GuavaCache Metric Support (code formatting fixed) * ENG-5066: GuavaCacheMetric Support, Fixed test-cases * ENG 5066: GuavaCacheMetric; Added test for cache size, Better efficient meter access * ENG 5066: GuavaCacheMetric Support, formatting issues * ENG 5066: GuavaCacheMetrics, Made comments more verbose * ENG 5066: GuavaCacheMetrics, Made comments more verbose Co-authored-by: Apoorv Jain <[email protected]>
1 parent 2152b66 commit 3be16d9

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

platform-metrics/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dependencies {
2323
implementation("io.prometheus:simpleclient_servlet:0.6.0")
2424
implementation("io.prometheus:simpleclient_pushgateway:0.9.0")
2525
implementation("org.eclipse.jetty:jetty-servlet:9.4.42.v20210604")
26+
implementation ("com.google.guava:guava:30.1.1-jre")
2627

2728
testImplementation("org.junit.jupiter:junit-jupiter:5.7.1")
2829
testImplementation("org.mockito:mockito-core:3.8.0")

platform-metrics/src/main/java/org/hypertrace/core/serviceframework/metrics/PlatformMetricsRegistry.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.codahale.metrics.jvm.JvmAttributeGaugeSet;
99
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
1010
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
11+
import com.google.common.cache.Cache;
1112
import com.typesafe.config.Config;
1213
import io.github.mweirauch.micrometer.jvm.extras.ProcessMemoryMetrics;
1314
import io.github.mweirauch.micrometer.jvm.extras.ProcessThreadMetrics;
@@ -19,6 +20,7 @@
1920
import io.micrometer.core.instrument.MeterRegistry;
2021
import io.micrometer.core.instrument.Tag;
2122
import io.micrometer.core.instrument.Timer;
23+
import io.micrometer.core.instrument.binder.cache.GuavaCacheMetrics;
2224
import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics;
2325
import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics;
2426
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
@@ -375,9 +377,17 @@ public static DistributionSummary registerDistributionSummary(String name,
375377
}
376378

377379
/**
378-
* Registers metrics for the given executor service with the service's metric registry and
379-
* reports them periodically to the configured reporters. Apart from the given tags, the
380-
* reporting service's default tags also will be reported with the metrics.
380+
* Registers metrics for GuavaCaches using micrometer's GuavaCacheMetrics under the given
381+
* cacheName for the given guavaCache
382+
*/
383+
public static <K, V> void registerCache(String cacheName, Cache<K, V> guavaCache) {
384+
GuavaCacheMetrics.monitor(METER_REGISTRY, guavaCache, cacheName);
385+
}
386+
387+
/**
388+
* Registers metrics for the given executor service with the service's metric registry and reports
389+
* them periodically to the configured reporters. Apart from the given tags, the reporting
390+
* service's default tags also will be reported with the metrics.
381391
*
382392
* See https://micrometer.io/docs/ref/jvm for more details on the metrics.
383393
*/

platform-metrics/src/test/java/org/hypertrace/core/serviceframework/metrics/PlatformMetricsRegistryTest.java

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import static org.junit.jupiter.api.Assertions.assertEquals;
44
import static org.junit.jupiter.api.Assertions.assertTrue;
55

6+
import com.google.common.cache.Cache;
7+
import com.google.common.cache.CacheBuilder;
68
import com.typesafe.config.Config;
79
import com.typesafe.config.ConfigFactory;
810
import io.micrometer.core.instrument.Counter;
@@ -13,6 +15,7 @@
1315
import java.util.HashMap;
1416
import java.util.List;
1517
import java.util.Map;
18+
import java.util.concurrent.Callable;
1619
import java.util.concurrent.TimeUnit;
1720
import java.util.concurrent.atomic.AtomicInteger;
1821
import java.util.stream.Collectors;
@@ -151,9 +154,66 @@ public void testDistributionSummary() {
151154
assertEquals(1, distribution.count());
152155
assertEquals(100, distribution.totalAmount());
153156
assertTrue(
154-
Arrays.stream(distribution.takeSnapshot().percentileValues()).map(m -> m.percentile())
155-
.collect(
156-
Collectors.toList()).containsAll(List.of(0.5, 0.95, 0.99)));
157+
Arrays.stream(distribution.takeSnapshot().percentileValues())
158+
.map(m -> m.percentile())
159+
.collect(Collectors.toList())
160+
.containsAll(List.of(0.5, 0.95, 0.99)));
161+
}
162+
163+
@Test
164+
public void testCache() throws Exception {
165+
initializeCustomRegistry(List.of("testing"));
166+
Cache<String, Integer> cache = CacheBuilder.newBuilder().maximumSize(10).recordStats().build();
167+
168+
PlatformMetricsRegistry.registerCache("my.cache", cache);
169+
Callable<Integer> loader =
170+
new Callable<Integer>() {
171+
@Override
172+
public Integer call() throws Exception {
173+
return -1;
174+
}
175+
};
176+
177+
// Doing some cache activity
178+
cache.put("One", 1);
179+
cache.put("Two", 2);
180+
cache.get("One", loader); // hit
181+
cache.get("Two", loader); // hit
182+
cache.get("Two", loader); // hit
183+
cache.get("Three", loader); // miss hence loaded from loader
184+
cache.get("Failed", loader); // miss hence loaded from loader
185+
/*
186+
* Cache = {One,Two, Three, Failed}
187+
* Cache Hit is basically the number of times cache.get returned an entry which was present in the cache, hence hit = 3
188+
* Cache Miss is basically the number of times cache.get returned an entry not present in the cache (hence loaded from loader), hence miss = 2
189+
* The way cache.get works is that if there is a cache miss then the entry is loaded from the loader and included in the cache,
190+
hence the cache size due to the above activity would be 2 (already put One,Two) + 2 (cache miss on Three, Failed) = 4
191+
192+
Expected hit count = 3.0, miss count = 2.0, cache size = 4
193+
*/
194+
195+
// Checking Cache Stats from registry
196+
double hits = 0, misses = 0,size = 0;
197+
hits = PlatformMetricsRegistry.getMeterRegistry().get("cache.gets").tag("result","hit").meter().measure().iterator().next().getValue();
198+
misses = PlatformMetricsRegistry.getMeterRegistry().get("cache.gets").tag("result","miss").meter().measure().iterator().next().getValue();
199+
size = PlatformMetricsRegistry.getMeterRegistry().get("cache.size").meter().measure().iterator().next().getValue();
200+
201+
assertEquals(3.0, hits);
202+
assertEquals(2.0, misses);
203+
assertEquals(4.0,size);
204+
205+
// Doing some more cache activity
206+
cache.get("NotPresent", loader); // miss hence loaded from loader
207+
208+
// Cache = {One,Two,Three,Failed,NotPresent}
209+
// expected hit=3.0, miss=3.0, size=5.0
210+
hits = PlatformMetricsRegistry.getMeterRegistry().get("cache.gets").tag("result","hit").meter().measure().iterator().next().getValue();
211+
misses = PlatformMetricsRegistry.getMeterRegistry().get("cache.gets").tag("result","miss").meter().measure().iterator().next().getValue();
212+
size = PlatformMetricsRegistry.getMeterRegistry().get("cache.size").meter().measure().iterator().next().getValue();
213+
214+
assertEquals(3.0, hits);
215+
assertEquals(3.0, misses);
216+
assertEquals(5.0,size);
157217
}
158218

159219
@Test

0 commit comments

Comments
 (0)