Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added examples of cache usage #4569

Merged
merged 1 commit into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ asciidoc:
chomp: 'all'
include-java: 'example$docs-src/test/java/io/micrometer/docs'
include-resources: 'example$docs-src/test/resources'
include-core-test-java: 'example$core-test'
1 change: 1 addition & 0 deletions docs/modules/ROOT/examples/core-test
94 changes: 94 additions & 0 deletions docs/modules/ROOT/pages/reference/cache.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
[[overview]]
= Micrometer Cache Instrumentations

Micrometer supports binding metrics to a variety of different popular caching libraries. Each implementation supports basic features, such as cache hits versus misses, from which you can derive basic information about the cache hit ratio over a period of time. Micrometer uses a function tracking counter to monitor such things as hits and misses, giving you a notion not only of hits and misses over the total life of the cache (the basic metric exposed from Guava's `CacheStats`, for example) but hits and misses inside a given interval.

[[cache-example]]
== Example

To demonstrate the features of cache monitoring, we start with a simple program that uses `reactor-netty` to read the entirety of Mary Shelley's _Frankenstein_ and put each word in the cache if it has not yet been seen:

====
Expand Down Expand Up @@ -42,3 +48,91 @@ The following image shows the miss ratio when it exceeds 10%:

.Alerting when the miss ratio exceeds 10%
image::reference/cache/grafana-guava-miss-ratio.png[Miss ratio (alerted),width=800]

== Cache implementations

Micrometer can instrument various cache implementations

* <<cache-caffeine, Caffeine>>
* <<cache-ehcache, EhCache>>
* <<cache-guava, Guava>>
* <<cache-hazelcast, Hazelcast>>
* <<cache-jcache, JCache>>

[[cache-caffeine]]
=== Caffeine

[source,java,subs=+attributes]
-----
// Setting up instrumentation
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/CaffeineCacheMetricsTest.java[tags=setup, indent=0]
// Binding manually
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/CaffeineCacheMetricsTest.java[tags=register, indent=0]
// Binding through a static method
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/CaffeineCacheMetricsTest.java[tags=monitor, indent=0]
-----

[[cache-ehcache]]
=== EhCache2

[source,java,subs=+attributes]
-----
// Setting up instrumentation
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/EhCache2MetricsTest.java[tags=setup, indent=0]
// Binding manually
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/EhCache2MetricsTest.java[tags=register, indent=0]
// Binding through a static method
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/EhCache2MetricsTest.java[tags=monitor, indent=0]
-----

[[cache-guava]]
=== Guava

[source,java,subs=+attributes]
-----
// Setting up instrumentation
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/GuavaCacheMetricsTest.java[tags=setup, indent=0]
// Binding manually
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/GuavaCacheMetricsTest.java[tags=register, indent=0]
// Binding through a static method
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/GuavaCacheMetricsTest.java[tags=monitor, indent=0]
-----

[[cache-hazelcast]]
=== Hazelcast

[source,java,subs=+attributes]
-----
// Setting up instrumentation
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/HazelcastCacheMetricsTest.java[tags=setup, indent=0]
// Binding manually
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/HazelcastCacheMetricsTest.java[tags=register, indent=0]
// Binding through a static method
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/HazelcastCacheMetricsTest.java[tags=monitor, indent=0]
-----

[[cache-jcache]]
=== JCache

[source,java,subs=+attributes]
-----
// Setting up instrumentation
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/JCacheMetricsTest.java[tags=setup, indent=0]
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/JCacheMetricsTest.java[tags=setup_2, indent=0]
// Binding manually
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/JCacheMetricsTest.java[tags=register, indent=0]
// Binding through a static method
include::{include-core-test-java}/io/micrometer/core/instrument/binder/cache/JCacheMetricsTest.java[tags=monitor, indent=0]
-----

Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,20 @@
*/
class CaffeineCacheMetricsTest extends AbstractCacheMetricsTest {

private LoadingCache<String, String> cache = Caffeine.newBuilder().build(key -> "");
// tag::setup[]
LoadingCache<String, String> cache = Caffeine.newBuilder().build(key -> "");

private CaffeineCacheMetrics<String, String, Cache<String, String>> metrics = new CaffeineCacheMetrics<>(cache,
"testCache", expectedTag);
CaffeineCacheMetrics<String, String, Cache<String, String>> metrics = new CaffeineCacheMetrics<>(cache, "testCache",
expectedTag);

// end::setup[]

@Test
void reportExpectedGeneralMetrics() {
// tag::register[]
MeterRegistry registry = new SimpleMeterRegistry();
metrics.bindTo(registry);
// end::register[]

verifyCommonCacheMetrics(registry, metrics);

Expand All @@ -64,8 +69,10 @@ void reportExpectedGeneralMetrics() {

@Test
void constructInstanceViaStaticMethodMonitor() {
// tag::monitor[]
MeterRegistry meterRegistry = new SimpleMeterRegistry();
CaffeineCacheMetrics.monitor(meterRegistry, cache, "testCache", expectedTag);
// end::monitor[]

meterRegistry.get("cache.eviction.weight").tags(expectedTag).functionCounter();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,19 @@ class EhCache2MetricsTest extends AbstractCacheMetricsTest {

private static CacheManager cacheManager;

private static Cache cache;
// tag::setup[]
static Cache cache;

private EhCache2Metrics metrics = new EhCache2Metrics(cache, expectedTag);
EhCache2Metrics metrics = new EhCache2Metrics(cache, expectedTag);

// end::setup[]

@Test
void reportMetrics() {
// tag::register[]
MeterRegistry registry = new SimpleMeterRegistry();
metrics.bindTo(registry);
// end::register[]

verifyCommonCacheMetrics(registry, metrics);

Expand Down Expand Up @@ -117,8 +122,10 @@ void reportMetrics() {

@Test
void constructInstanceViaStaticMethodMonitor() {
// tag::monitor[]
MeterRegistry meterRegistry = new SimpleMeterRegistry();
EhCache2Metrics.monitor(meterRegistry, cache, expectedTag);
// end::monitor[]

meterRegistry.get("cache.remoteSize").tags(expectedTag).gauge();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,24 @@
*/
class GuavaCacheMetricsTest extends AbstractCacheMetricsTest {

private LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(new CacheLoader<String, String>() {
// tag::setup[]
LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(new CacheLoader<String, String>() {
public String load(String key) throws Exception {
return "";
}
});

private GuavaCacheMetrics<String, String, Cache<String, String>> metrics = new GuavaCacheMetrics<>(cache,
"testCache", expectedTag);
GuavaCacheMetrics<String, String, Cache<String, String>> metrics = new GuavaCacheMetrics<>(cache, "testCache",
expectedTag);

// end::setup[]

@Test
void reportExpectedMetrics() {
// tag::register[]
MeterRegistry registry = new SimpleMeterRegistry();
metrics.bindTo(registry);
// end::register[]

verifyCommonCacheMetrics(registry, metrics);

Expand Down Expand Up @@ -74,8 +79,10 @@ void reportExpectedMetrics() {

@Test
void constructInstanceViaStaticMethodMonitor() {
// tag::monitor[]
MeterRegistry meterRegistry = new SimpleMeterRegistry();
GuavaCacheMetrics.monitor(meterRegistry, cache, "testCache", expectedTag);
// end::monitor[]

meterRegistry.get("cache.load.duration").tags(expectedTag).timeGauge();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,19 @@
*/
class HazelcastCacheMetricsTest extends AbstractCacheMetricsTest {

private static IMap<String, String> cache;
// tag::setup[]
static IMap<String, String> cache;

private HazelcastCacheMetrics metrics = new HazelcastCacheMetrics(cache, expectedTag);
HazelcastCacheMetrics metrics = new HazelcastCacheMetrics(cache, expectedTag);

// end::setup[]

@Test
void reportMetrics() {
// tag::register[]
MeterRegistry meterRegistry = new SimpleMeterRegistry();
metrics.bindTo(meterRegistry);
// end::register[]

verifyCommonCacheMetrics(meterRegistry, metrics);

Expand Down Expand Up @@ -102,8 +107,10 @@ void reportMetrics() {

@Test
void constructInstanceViaStaticMethodMonitor() {
// tag::monitor[]
MeterRegistry meterRegistry = new SimpleMeterRegistry();
HazelcastCacheMetrics.monitor(meterRegistry, cache, expectedTag);
// end::monitor[]

meterRegistry.get("cache.partition.gets").tags(expectedTag).functionCounter();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,29 @@
class JCacheMetricsTest extends AbstractCacheMetricsTest {

@SuppressWarnings("unchecked")
private Cache<String, String> cache = mock(Cache.class);
// tag::setup[]
Cache<String, String> cache;

private CacheManager cacheManager = mock(CacheManager.class);
JCacheMetrics<String, String, Cache<String, String>> metrics;

private JCacheMetrics<String, String, Cache<String, String>> metrics;
// end::setup[]

private CacheManager cacheManager;

private MBeanServer mbeanServer;

private Long expectedAttributeValue = new Random().nextLong();

@BeforeEach
void setup() throws Exception {
cache = mock(Cache.class);
cacheManager = mock(CacheManager.class);
when(cache.getCacheManager()).thenReturn(cacheManager);
when(cache.getName()).thenReturn("testCache");
when(cacheManager.getURI()).thenReturn(new URI("http://localhost"));
// tag::setup_2[]
metrics = new JCacheMetrics<>(cache, expectedTag);
// end::setup_2[]

// emulate MBean server with MBean used for statistic lookup
mbeanServer = MBeanServerFactory.createMBeanServer();
Expand All @@ -75,8 +82,10 @@ void tearDown() {

@Test
void reportExpectedMetrics() {
// tag::register[]
MeterRegistry meterRegistry = new SimpleMeterRegistry();
metrics.bindTo(meterRegistry);
// end::register[]

verifyCommonCacheMetrics(meterRegistry, metrics);

Expand All @@ -86,8 +95,10 @@ void reportExpectedMetrics() {

@Test
void constructInstanceViaStaticMethodMonitor() {
// tag::monitor[]
MeterRegistry meterRegistry = new SimpleMeterRegistry();
JCacheMetrics.monitor(meterRegistry, cache, expectedTag);
// end::monitor[]

meterRegistry.get("cache.removals").tags(expectedTag).gauge();
}
Expand Down