List of JMX objects and attributes? - java

I am trying to implement a nagios plugin, and doing so requires that I know specifically what object and attribute I want to monitor. The thing is, I haven't been able to find a listing anywhere of the standard system jmx objects and attributes. Can anyone point me in the right direction? I need to monitor things like memory pools, heap size, etc.

You can use
Set mbeans = mBeanServer.queryNames(null, null);
for (Object mbean : mbeans)
{
WriteAttributes(mBeanServer, (ObjectName)mbean);
}
private void WriteAttributes(final MBeanServer mBeanServer, final ObjectName http)
throws InstanceNotFoundException, IntrospectionException, ReflectionException
{
MBeanInfo info = mBeanServer.getMBeanInfo(http);
MBeanAttributeInfo[] attrInfo = info.getAttributes();
System.out.println("Attributes for object: " + http +":\n");
for (MBeanAttributeInfo attr : attrInfo)
{
System.out.println(" " + attr.getName() + "\n");
}
}
This will write all the object names and their attributes...

You can always use mBeanServer.queryNames(null, null); for getting to all MBeans registered at a certain MBeanServer (where mBeanServer is the MBeanServerConnection which you obtained either locally or remotely).
However, before implementing your own Nagios Plugins, why not using an already exisiting one ? E.g. jmx4perl's check_jmx4perl which comes with tools for exploring the JMX namespace (like jmx4perl <url> list for listing all JMX MBeans with their attributes and operations or j4psh a readline based JMX shell with context sensitive command line completion).

From a sysadmin point of view, I fully understand the bases for the question. The standard JMX documentation, or the objects one can encounter while trying to browse JMX object trees, can be overwhelming and confusing.
I have found this Op5 KB article quite useful in providing a decent overview of JMX objects of interest for JBoss.
Obviously, one needs to adjust to fit with the monitoring system they are actually using, but there is enough in the examples for whatever nagios-based monitoring system is being used.

Are you looking for the JVM platform MBean docs?
There are examples there on to get the MBeans and interrogate them e.g.
The ThreadMXBean platform MBean
provides support for monitoring thread
contention and thread CPU time.

Check out MC4J or JConsole - it's trivial to get going with both of 'em.

Related

How can I get the enqueue and dequeue count for an ActiveMQ queue WITHIN my Java Spring app?

I have been scouring the internet for documentation on this and it's unbelievable how difficult it is to find. My goal is to create a REST endpoint where I can return queue details such as enqueue, dequeue, etc. counts for a custom dashboard I am making.
I keep seeing documentation such as this, this, and this, but I can't seem to figure out how to get these details in my actual program. I have gotten about as far as using the JMX GUI, but that really is not the direction I need to be going. Can anyone help me figure out how to get simple connection to a broker that will return these details? I really have tried to research this, but I have not been able to figure out a way to incorporate this information to my application in any meaningful away.
The way to monitor the broker is via the broker JMX endpionts and the management beans it exposes. Other means would be through the Jolokia REST API that exposes those same MBeans. One article showing how to use the Jolokia bits is here.
A brief example of using JMX with ActiveMQ is below.
// connection
String url = "service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi";
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(url));
MBeanServerConnection connection = connector.getMBeanServerConnection();
// get queue size
ObjectName nameConsumers = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=myqueue");
DestinationViewMBean mbView = MBeanServerInvocationHandler.newProxyInstance(connection, nameConsumers, DestinationViewMBean.class, true);
long queueSize = mbView.getQueueSize();

C3P0Registry mbean is not being registered with MBeanServer. Getting InstanceNotFoundException

I am trying to get dbpool details using my function named getdbPoolStatistics() which returns a hashmap of all the metrices that i'm gonna monitor.
In getdbPoolStatistics(), i use C3P0Registry.getPooledDataSources() which returns 2 db pools and then access the pools using an iterator i.e. connectionIterator .
To get token , which is further used during ObjectName creation.
ArrayList<String> pooledDataSourcesIdentityTokenList = new ArrayList<String>();
mbean that gives you monitoring info.
Iterator<PooledDataSource> connectionIterator = C3P0Registry.getPooledDataSources().iterator();
Get token and add it to ArrayList.
while(connectionIterator.hasNext()) {
pooledDataSourcesIdentityTokenList.add(connectionIterator.next().getIdentityToken());
}
After this we need to get MBeanServer
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
While registering mbean, I have used Domain: com.mchange.v2.c3p0, key-value: type=PooledDataSource and identityToken= token that i had added to ArrayList for 2 db pool objects from C3P0Registry.
Now, if i register the ObjectName using mbs.registerMBean()
for (int i = 0; i < pooledDataSourcesIdentityTokenList.size() ; i++) {
ObjectName objName = new ObjectName("com.mchange.v2.c3p0:type=PooledDataSource,identityToken="+pooledDataSourcesIdentityTokenList.get(i)+",*");
mbs.registerMBean(connectionIterator2.next(), objName.getInstance("com.mchange.v2.c3p0","identityToken",pooledDataSourcesIdentityTokenList.get(i)));
}
i get
:error: unreported exception InstanceAlreadyExistsException; must be caught or declared to be thrown
Now if i use the complete objects instead of iterating over it.
for (int i = 0; i < pooledDataSourcesIdentityTokenList.size() ; i++) {
ObjectName objName = new ObjectName("com.mchange.v2.c3p0:type=PooledDataSource,identityToken="+pooledDataSourcesIdentityTokenList.get(i)+",*");
mbs.registerMBean(C3P0Registry.getPooledDataSources() , objName);
startTimeMillisArray[i] = (String)(mbs.getAttribute(objName, "startTimeMillisDefaultUser"));
}
I get :
error: unreported exception InstanceAlreadyExistsException; must be caught or declared to be thrown mbs.registerMBean(C3P0Registry.getPooledDataSources() , objName);
As InstanceAlreadyExistsException, i thought of not registering MBean
Also I found that registerMBean(), was not used in many examples so i removed that line of code and tried.
If i only keep make the ObjectName and then try to getAttribute and put it in startTimeMillisArray
for (int i = 0; (i < pooledDataSourcesIdentityTokenList.size() ; i++) {
ObjectName objName = new ObjectName("com.mchange.v2.c3p0:type=PooledDataSource,identityToken="+pooledDataSourcesIdentityTokenList.get(i)+",*");
//No registering mbean here.
startTimeMillisArray[i] = (String)(mbs.getAttribute(objName, "startTimeMillisDefaultUser"));
}
then I get the error:
javax.management.InstanceNotFoundException: com.mchange.v2.c3p0:type=PooledDataSource,identityToken=2ufaha9lm5mbruczledo|86ffe7,*
javax.management.InstanceNotFoundException: com.mchange.v2.c3p0:type=PooledDataSource,identityToken=2ufaha9lm5mbruczledo|c7dca5,*
This is creating a lot of confusion whether to use registerMBean() or not and also if I am using it the right way? Please help.
I think you may be doing a lot more work than you need to.
c3p0 registers its MBeans by default. If you don't want them registered, you have to work at that. If you are having trouble monitoring c3p0 pools and its registry, you may need to debug general JMX stuff. Do you see other MBeans on the same JVM? If not, you may need to set some System properties. See here for some tips.
You only have to do anything special if you want to turn JMX registration OFF in c3p0, that is, if you want to disable JMX MBean registration.
You can also give your c3p0 MBeans customized and/or stable names.
But you should never have to get into low-level JMX APIs, like defining your own ObjectName objects. c3p0 takes care of that for you.
Please see the JMX section of c3p0's docs, here.
p.s. c3p0 includes no getdbPoolStatistics() method, that may be part of your own libraries.

java.rmi.NotBoundException . Discovering what bindings are available

Below are the bindings of implementation of java.rmi.registry.Registry
CustomRegistry: registryCount = 2
reg1.com:11, # of bindings = 2
OPTIONS
UPDATES
reg2.com:11, # of bindings = 1
TEST
When I use
(MyRegistry)registry.lookup("OPTIONS");
I receive exception: java.rmi.NotBoundException: OPTIONS
After reading explanations of this exception on this site then it appears the binding "OPTIONS" is not discoverable.
As the RMI servers are on a different machine is there a mechanism I can use to discover the bindings available on servers reg1.com % reg2.com
After reading explanations of this exception on this site then it appears the binding "OPTIONS" is not discoverable.
No it doesn't. It means it isn't bound.
As the RMI servers are on a different machine
Irrelevant.
is there a mechanism I can use to discover the bindings available on servers reg1.com % reg2.com
Registry.list(). Any string returned by Registry.list() can be plugged directly into Registry.lookup() to return the binding, unless it was unbound in between, which isn't likely.
Similarly any string returned by Naming.list() can be plugged into Naming.lookup().
But you can't mix them up, e.g. passing a string returned by Registry.list() to Naming.lookup(), because Naming deals in RMI URLs where Registry just deals in names.

How do I change the port used for livetribe SLP?

I'm attempting to use LiveTribe SLP module (http://livetribe.codehaus.org/LiveTribe-SLP) to provide an SLP service for an application. I want to change the port from 427 to something else entirely. The documentation is sparse and even more confusing is that in the FAQ, it claims to link to an example that would show me exactly what I'm looking for. Unfortunately, it doesn't (unless I'm overlooking something). Does anyone know how to do this?
There is a client and server example here:
http://livetribe.org/SLP-Examples-JMX
(Link broken.)
These are the important lines on the server side:
// Allow this code to be run by non-root users on Linux/Unix
Settings settings = new MapSettings();
settings.put(Keys.PORT_KEY, 4427);
// Create the SLP ServiceAgent that advertises the JMX service
ServiceAgent serviceAgent = SLP.newServiceAgent(settings);
And on the client side:
// Allow this code to be run by non-root users on Linux/Unix
Settings settings = new MapSettings();
settings.put(Keys.PORT_KEY, 4427);
// Create the SLP UserAgentClient that discovers services
UserAgentClient userAgentClient = SLP.newUserAgentClient(settings);
Sorry about the bad documentation. We've had problems with it ever since we changed the L&F of the site to use Twitter Bootstrap.
The page should now fully render:
http://livetribe.org/SLP-Examples-JMX
Link broken.

Check domain availability Java

Is there a relatively simple way in Java to check if a domain is available or not?
I need a reliable method, so only checking if the connection can be made is not enough.
Domain availability depends on having a whois client. Here is a link to an implementation of a whois client in Java:
Java Whois Client
You'll need to parse the results - and depending on what whois server you use, you may (will) have varying formats that are returned. The best thing to do is to pay for a commercial whois/registration service such as OpenSRS. They have an extensive API which you can use as a registered reseller. Here are the API docs:
http://opensrs.com/resources/documentation/opensrs_xmlapi.pdf
HTH,
-aj
There's a good Whois Java client here:
https://github.com/ethauvin/Whois
You can run it from the command line or interface with it directly:
// don't include the www
Whois.main(new String[] {"skytouch.com"});
Another solution is to use Apache Commons lib. Simplified example:
import org.apache.commons.net.whois.WhoisClient;
public String getWhois(String domainName){
WhoisClient whois = new WhoisClient();
whois.setConnectTimeout(10000);
whois.setDefaultTimeout(10000);
whois.connect("whois.verisign-grs.com", 43);
String domainWhois = whois.query(domainName);
whois.disconnect();
return domainWhois;
}
Check if response equals "no match". Whois servers, timeout length and no availability response differ according to extension so you should have prepared additional collections for them.
Whois servers list can be found:
http://www.mit.edu/afs/athena/contrib/potluck/Net-Services/whois-servers.list
https://raw.githubusercontent.com/whois-server-list/whois-server-list/master/whois-server-list.xml
http://www.nirsoft.net/whois_servers_list.html
If you try to make your queries concurrent, you will definitely get whois response "You have reached configured rate limit." or explicit exception in a code so you should repeat queries after some sleep.
Performing a DNS lookup on the domain is the easiest solution. All available domains will have no DNS record, and most registrars assign a default DNS entry upon registration.
WHOIS lookups will be your most reliable solution, particularly behind an ISP that spoofs their own server (with a "domain not found" page filled with ads) for any missing domain name.

Categories