Skip to content

Provide an API to retrieve statistics #423

Open
@chrisknoll

Description

@chrisknoll

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:

  1. The name of the cache manager isn't exactly a URI because ObjectNames can not have : in them, but URIs do.
  2. 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.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions