Reputation: 129
I have implemented two cacheManagers.
One using caffiene and one using redis.
I have exposed them as beans and they are working as expected of them.
There isn't any cache endpoint in the list available at /actuator/metrics path either.
I was able to only load /actuator/caches and /actuator/caches/{cacheName} endpoint. These endpoint only show the name and class of the cache being used. I am unable to see any metrics related to them.
I am using springboot 2.1.3 and spring-boot-actuator.
@Bean
public CacheManager caffeine() {
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCaffeine(caffeineCacheBuilder());
return caffeineCacheManager;
}
private Caffeine<Object, Object> caffeineCacheBuilder() {
return Caffeine.newBuilder().
initialCapacity(initialCapacity).
maximumSize(maxCapacity).
expireAfterAccess(Duration.parse(ttl)).
recordStats();
}
Upvotes: 5
Views: 7698
Reputation: 828
I would like to emphasize Punit Kulal's suggestion. If you are not configuring your caches explicitly, CacheMetricsRegistirar
cannot register your caches to micrometer. You need to create caches statically and then consume them with @Cacheable(cacheNames = "yourCacheName")
. In this example I'm using cache2k implementation, feel free to change it according to yours.
First make sure that your caching implementation's micrometer binder library is added as dependency:
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-micrometer</artifactId>
</dependency>
Explicitly create your caches:
@Configuration
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
SpringCache2kCacheManager manager = new SpringCache2kCacheManager();
manager.addCache("yourCacheName",
cache2kBuilder -> cache2kBuilder.entryCapacity(10L).expireAfterWrite(12L, TimeUnit.HOURS));
return manager;
}
}
You can still consume your cache with @Caching
annotation but this time it's not created on the fly:
@Service
public class CacheableService {
@Cacheable(cacheNames = "yourCacheName")
public StockDetailResponse getExchanges(String symbol, LocalDate date) {
return "Cached";
}
}
As a side note you should be able to see cache related fields when you send GET request to http://localhost:8080/actuator/metrics
{
"names": [
"application.ready.time",
"application.started.time",
"cache.evictions",
"cache.gets",
"cache.puts",
"cache.size",
]
}
Now you can access cache hit counts by following GET request:
curl 'http://localhost:8080/actuator/metrics/cache.gets'
Response:
{
"name": "cache.gets",
"description": "The number of times cache lookup methods have returned a cached (hit) or uncached (newly loaded or null) value (miss).",
"measurements": [
{
"statistic": "COUNT",
"value": 0.0
}
],
"availableTags": [
{
"tag": "valueType=",
"values": [
"Object"
]
},
{
"tag": "result",
"values": [
"hit",
"miss"
]
},
{
"tag": "cache.manager",
"values": [
"cacheManager"
]
},
{
"tag": "keyType=",
"values": [
"Object"
]
},
{
"tag": "cache",
"values": [
"symbols"
]
},
{
"tag": "cache2kCacheManager",
"values": [
"springDefault"
]
},
{
"tag": "name",
"values": [
"yourCacheName"
]
}
]
}
Upvotes: 1
Reputation: 129
Turned out @Cacheable makes the cache dynamically at runtime, thus if we want the annotated caches to have metrics, we have to set the cache names explicitly in the cacheManagerBean which inturn makes the cacheManager static.
Or create a custom registryBinder as stated in after upgrade to Spring Boot 2, how to expose cache metrics to prometheus?
and call the register method only after the cache is created.
Upvotes: 4