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

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.

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

No branches or pull requests

1 participant