Reading JBoss Memory Usage using Java JMX


Monitoring memory usage of JBoss Server through Java is not hard if you really know the piece of code I am going to write here. But, probably using these java codes for monitoring Jboss is not a real good idea as Jboss provides their own free tool for it.
Let's divide the code in small parts.

Section 1: Connect to JBoss Server which is in a remote machine

 
ModelControllerClient client = null;
try {
 client = createClient(InetAddress.getByName("172.16.73.12"), 9999,
     "admin", "pass", "ManagementRealm");
    } 
catch (UnknownHostException e) {
 e.printStackTrace();
}

In the above code createClient is the method which will create the connection.
The IP address & port number mentioned above is the IP address and the port number, where the JBoss is running.
The parameters - "admin", "pass", "ManagemntRealm" are the username, password and security realms for JBoss Server.
ModelControllerClient is the class which stored the client details which is created using createClient method.







 
private ModelControllerClient createClient(final InetAddress host,
  final int port, final String username, final String password,
  final String securityRealmName) {

 final CallbackHandler callbackHandler = new CallbackHandler() {

  public void handle(Callback[] callbacks) throws IOException,
    UnsupportedCallbackException {
   for (Callback current : callbacks) {
    if (current instanceof NameCallback) {
     NameCallback ncb = (NameCallback) current;
     ncb.setName(username);
    } else if (current instanceof PasswordCallback) {
     PasswordCallback pcb = (PasswordCallback) current;
     pcb.setPassword(password.toCharArray());
    } else if (current instanceof RealmCallback) {
     RealmCallback rcb = (RealmCallback) current;
     rcb.setText(rcb.getDefaultText());
    } else {
     throw new UnsupportedCallbackException(current);
    }
   }
  }
 };
 return ModelControllerClient.Factory
   .create(host, port, callbackHandler);
}

Now, as the connection is created and we have already got the client details in our ModelControllerClient object , we can proceed for reading the details for the server.

Section 2: Reading details from the Server

a. Create Request & Execute the Request:
 
ModelNode request = new ModelNode();
request.get(ClientConstants.OP).set("read-resource");
request.get("include-runtime").set(true);
request.get("recursive").set(true);
request.get(ClientConstants.OP_ADDR).add("subsystem", "datasources");

ModelNode response = client.execute(new OperationBuilder(request)
  .build());

The Response what we get here is a XML response.
(Tip : To see the whole response, one can just print the response in System Console.)

b. Read Datasources:

ModelNode datasources = response.get(ClientConstants.RESULT).get(
  "data-source");
ArrayList listOfDatasources = new ArrayList();
if (datasources.isDefined()) {
 for (ModelNode dataSource : datasources.asList()) {
  String dataSourceName = dataSource.asProperty().getName();
  if (null != dataSourceName && dataSourceName.length() > 0) {
   listOfDatasources.add(dataSourceName);
  }
 }
}
System.out.println("Datasources : " + listOfDatasources.toString());

Section 3: Read the details of each and every datasources









ArrayList datasourceStatisticsBeanList = new ArrayList();

for (int i = 0; i < listOfDatasources.size(); i++) {
 System.out.println("Reading datasource details for : "
   + listOfDatasources.get(i));
 ModelNode datasourceDetails = datasources.get(listOfDatasources
   .get(i));
 ModelNode dataPoolStats = ((ModelNode) (datasourceDetails
   .get("statistics"))).get("pool");
 DataSourceStatisticsBean dataSourceStatisticsBean = new DataSourceStatisticsBean()
   .createDataSourceStatisticsBean(listOfDatasources.get(i),
     Integer.parseInt(process((dataPoolStats
       .get("ActiveCount").toString()))), 
     Integer.parseInt((process(dataPoolStats.get(
         "AvailableCount").toString()))),
     Integer.parseInt((process(dataPoolStats.get(
       "AverageBlockingTime").toString()))),
     Integer.parseInt((process(dataPoolStats.get(
       "AverageCreationTime").toString()))),
     Integer.parseInt((process(dataPoolStats.get(
       "CreatedCount").toString()))), 
     Integer.parseInt((process(dataPoolStats.get(
         "DestroyedCount").toString()))),
     Integer.parseInt((process(dataPoolStats.get(
       "MaxCreationTime").toString()))), 
     Integer.parseInt((process(dataPoolStats.get(
         "MaxUsedCount").toString()))),
     Integer.parseInt((process(dataPoolStats.get(
       "MaxWaitTime").toString()))), 
     Integer.parseInt((process(dataPoolStats.get(
         "TimedOut").toString()))), 
     Integer.parseInt((process(dataPoolStats.get(
         "TotalBlockingTime").toString()))),
     Integer.parseInt((process(dataPoolStats.get(
       "TotalCreationTime").toString()))));
 datasourceStatisticsBeanList.add(dataSourceStatisticsBean);
 System.out.println("Reading Datasource " + listOfDatasources.get(i)
   + " is completed!");

}
In the above code, we retrieved the details for every datasources for that Jboss and stored all the data I needed in a bean of data source. Here, Please note that, the class DataSourceStatisticsBean is a simple bean class created by me.
So.. this was the code.
With this code, what you need to do is : automate this code. This can be done in several ways.. you can use a batch job, or connect this code to a JSP page or use a EJB timer service, to run this code automatically after a few seconds.

In the following link, you can download the sample code I created. I  integrated this code to JSP which refreshed every  10 secs and displays the graph of the datasources using Google Visualization Framework.

Download JbossMonitor

Happy Learning!
Don't forget to comment and share!

No comments :

Post a Comment