Skip to content
New issue

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

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

Already on GitHub? # to your account

Provide an API to retrieve statistics #423

Open
chrisknoll opened this issue Aug 4, 2024 · 0 comments
Open

Provide an API to retrieve statistics #423

chrisknoll opened this issue Aug 4, 2024 · 0 comments

Comments

@chrisknoll
Copy link

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.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant