It appears that the JCache API does provide some mechanism to specify that statistics could be enabled:
@Component
public static class CachingSetup implements JCacheManagerCustomizer {
@Override
public void customize(CacheManager cacheManager) {
cacheManager.createCache("person", new MutableConfiguration<Integer, PersonDTO>()
.setTypes(Integer.class, PersonDTO.class)
.setStoreByValue(false)
.setStatisticsEnabled(true));
cacheManager.createCache("personList", new MutableConfiguration<Object, List<PersonDTO>>()
.setTypes(Object.class, (Class<List<PersonDTO>>)(Class<?>)List.class)
.setStoreByValue(false)
.setStatisticsEnabled(true));
}
}
But there's no API to retrieve these statistics. It seems that there is a CacheStatisticsMXBean that is used to access these statistics, but it's quite confusing and cumbersome to retrieve:
private CacheStatisticsMXBean getCacheStats(CacheManager cacheManager, String cacheName) throws Exception {
final MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
final Set<ObjectInstance> cacheBeans = beanServer.queryMBeans(
ObjectName.getInstance("javax.cache:type=CacheStatistics,CacheManager=*,Cache=*"),
null);
// the MXBean's CacheManager seems to leverage the URI of the cache manager, but : is replaced with .
// which I am not sure can be depended on in a cross-provider perspective
String cacheManagerName = cacheManager.getURI().toString().replace(":", ".");
ObjectInstance cacheBean = cacheBeans.stream()
.filter(b ->
b.getObjectName().getKeyProperty("CacheManager").equals(cacheManagerName)
&& b.getObjectName().getKeyProperty("Cache").equals(cacheName)
).findFirst().orElseThrow(() -> new IllegalAnnotationException(String.format("No cache found for cache manager = %s, cache = %s", cacheManagerName, cacheName)));
final CacheStatisticsMXBean cacheStatisticsMXBean = MBeanServerInvocationHandler.newProxyInstance(beanServer, cacheBean.getObjectName(), CacheStatisticsMXBean.class, false);
return cacheStatisticsMXBean;
}
So, many potential pitfalls about what we need to do here:
The name of the cache manager isn't exactly a URI because ObjectNames can not have : in them, but URIs do.
The name that is registered as a MXBean may be provider dependant and therefore difficult to mae provider-agnostic. Would be nice if you could name a CacheProvider that mapps directly to the queryMBean() call.
ManagementFactory.getPlatformMBeanServer() actually lets you query for beans that are produced system-wide, not application specific, leading to potential conflicts if you have 2 applications running that share cache names.
So, the ask here is if a minor update to the JCache (JSR107) API could provide an accessor to fetch a CacheStatisticsMXBean from a cache instance so that all these error-prone hurdles can be avoided, and you ask the cache directly for its statistics.
It appears that the JCache API does provide some mechanism to specify that statistics could be enabled:
But there's no API to retrieve these statistics. It seems that there is a CacheStatisticsMXBean that is used to access these statistics, but it's quite confusing and cumbersome to retrieve:
So, many potential pitfalls about what we need to do here:
ManagementFactory.getPlatformMBeanServer()
actually lets you query for beans that are produced system-wide, not application specific, leading to potential conflicts if you have 2 applications running that share cache names.So, the ask here is if a minor update to the JCache (JSR107) API could provide an accessor to fetch a
CacheStatisticsMXBean
from a cache instance so that all these error-prone hurdles can be avoided, and you ask the cache directly for its statistics.