views:

626

answers:

3

I'm using JMX to build a custom tool for monitoring remote Coherence clusters at work. I'm able to connect just fine and query MBeans directly, and I've acquired nearly all the information I need. However, I've run into a snag when trying to query MBeans for specific caches within a cluster, which is where I can find stats about total number of gets/puts, average time for each, etc.

The MBeans I'm trying to access programatically are visible when I connect to the remote process using JConsole, and have names like this:

Coherence:type=Cache,service=SequenceQueue,name=SEQ%GENERATOR,nodeId=1,tier=back

It would make it more flexible if I can dynamically grab all type=Cache MBeans for a particular node ID without specifying all the caches. I'm trying to query them like this:

QueryExp specifiedNodeId = Query.eq(Query.attr("nodeId"), Query.value(nodeId));
QueryExp typeIsCache = Query.eq(Query.attr("type"), Query.value("Cache"));
QueryExp cacheNodes = Query.and(specifiedNodeId, typeIsCache);
ObjectName coherence = new ObjectName("Coherence:*");
Set<ObjectName> cacheMBeans = mBeanServer.queryMBeans(coherence, cacheNodes);

However, regardless of whether I use queryMBeans() or queryNames(), the query returns a Set containing...

  • ...0 objects if I pass the arguments shown above
  • ...0 objects if I pass null for the first argument
  • ...all MBeans in the Coherence:* domain (112) if I pass null for the second argument
  • ...every single MBean (128) if I pass null for both arguments

The first two results are the unexpected ones, and suggest a problem in the QueryExp I'm passing, but I can't figure out what the problem is. I even tried just passing typeIsCache or specifiedNodeId for the second parameter (with either coherence or null as the first parameter) and I always get 0 results.

I'm pretty green with JMX — any insight on what the problem is? (FYI, the monitoring tool will be run on Java 5, so things like JMX 2.0 won't help me at this point.)

+2  A: 

Just wanted to post my solution for posterity...

I have been able to successfully retrieve the set of MBeans matching the specified characteristics through a simpler (yet stranger) approach. I still don't know why the QueryExp approach doesn't work, but here's what does work (replaces the last line of code in my question):

Set<ObjectName> cacheMBeans = mBeanServer.queryNames(new ObjectName("Coherence:type=Cache,nodeId="+nodeId+",*"), null);

It also works when adding a fragment service=SequenceQueue in the ObjectName constructor string to filter by Coherence service (cache) name.

As long as it works somehow, it's enough for me to get my job done, but this seems like a glaring flaw in the JMX implementation. And don't get me started on the process for creating a working JMXServiceURL using JMX and RMI...

Quinn Taylor
A: 

Quinn, I see that you're using Coherence and attempting to build some internal monitoring tools. Rather than building it yourself, have you checked out Evident Software's Coherence monitoring tool?

Ivan Ho
An SO answer is not the place product endorsement trolling... My tool is already complete, and tools like this yours (and RTView from SL.com) are not useful to us because they're GUI tools, and mine is a headless tool that runs automatically and raises alerts as necessary. Also, my tool introspects Coherence caches using internal business rules, and I'd have to write much of the same code anyway.
Quinn Taylor
+1  A: 

I fell down the same path as you, and I think the JDK docs could be clearer.

The Query.* appear to be only able to match attributes of the underlying MBean (i.e. real POJO getters), whereas ObjectName patterns is able to match against key/values within the ObjectName itself.

It would be nice to have the flexibility of doing more complex queries within the ObjectName domain.

Jon Travis