Monitor your JBoss resources using the DMR API

It is recommended that you check first the following article which will show you how to configure the management native interface on WildFly or JBoss EAP 7: How to use WildFly management API programmatically

This is a short do-it-yourself guide that will teach you how to monitor your WildFly / JBoss EAP 7 server resources using EJB 3 Timers and the JBoss DMR API.

 Supposing that you need to monitor a critical attribute of your server, such the Connection pool statistics and need to issue a warning if you are running out of JDBC Connections, for example.

The CLI provides the relevant pool statistics in the datasources subsystem, which can be obtained using the following command: (substitute the ExampleDS with the actual datasource you are using)

/subsystem=datasources/data-source=ExampleDS/statistics=pool/:read-resource(recursive=false,proxies=false,include-runtime=true,include-defaults=true)

which returns:

{
    "outcome" => "success",
    "result" => {
        "ActiveCount" => "1",
        "AvailableCount" => "20",
        "AverageBlockingTime" => "2",
        "AverageCreationTime" => "791",
        "CreatedCount" => "1",
        "DestroyedCount" => "0",
        "MaxCreationTime" => "791",
        "MaxUsedCount" => "1",
        "MaxWaitTime" => "1",
        "TimedOut" => "0",
        "TotalBlockingTime" => "2",
        "TotalCreationTime" => "791"
    }
}

On key runtime attribute of the Connection pool is the ActiveCount which returns the number of JDBC Connections which are currently “busy”. If you want to be notified when this number grows too much without the need to install any agent on your server, all you need is an EJB timer and the JBoss DMR API:

package com.sample;


import java.io.IOException;
import java.net.*;
import java.util.logging.Logger;

import javax.annotation.Resource;
import javax.ejb.*;
import javax.mail.Session;

import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.dmr.ModelNode;

import javax.mail.Session;
import javax.mail.Message;
import javax.mail.Transport;
import javax.mail.Address;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;


@Stateless
public class ResourceMonitor
{

    private final static Logger logger = Logger.getLogger(ResourceMonitor.class.getName());

    @Resource
    private TimerService timerService;

    @Resource(mappedName="java:jboss/mail/Default")
    private Session mailSession;

 

    @Schedule(dayOfWeek = "*", hour = "*", minute = "*", second = "*/30",year="*", persistent = false)
    public void backgroundProcessing()
    {
        logger.info("Timer is checking your resources........");
        
        ModelControllerClient client=null;
        try {
            client = ModelControllerClient.Factory.create(InetAddress.getByName("localhost"), 9999);
        } catch (UnknownHostException e) {
             
            e.printStackTrace();
        }         

        ModelNode op = new ModelNode();         

        op.get("operation").set("read-resource");           
        op.get("include-runtime").set(true);           

        ModelNode address = op.get("address");         

        address.add("subsystem", "datasources");           
        address.add("data-source", "ExampleDS");       
        address.add("statistics", "pool");           

        ModelNode returnVal=null;
        try {
            returnVal = client.execute(op);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        ModelNode node2 = returnVal.get("result");
        String _activeCount = node2.get("ActiveCount").asString();
        int activeCount = Integer.parseInt(_activeCount);
         
        if (activeCount > 20) {
            sendMessage("You are using too many Connections!");
        }


    }
    public void sendMessage(String txt) {
        try    {
            MimeMessage m = new MimeMessage(mailSession);
            Address from = new InternetAddress("senderemailaddress.com");
            Address[] to = new InternetAddress[] {new InternetAddress("receiveremailaddress.com") };

            m.setFrom(from);
            m.setRecipients(Message.RecipientType.TO, to);
            m.setSubject("JBoss AS 7 Warning");
            m.setSentDate(new java.util.Date());
            m.setContent(txt,"text/plain");
            Transport.send(m);
            logger.info("Mail sent!");
        }
        catch (javax.mail.MessagingException e)
        {
            e.printStackTrace();
            logger.severe("Error in Sending Mail: "+e);
        }
    }
}

This simple EJB timer fires an event every 30 seconds and checks for the value of the ActiveCount ModelNode. If the value exceeds 20 a mail is sent, using the default Mail Session.
In order to compile these application, add the following dependency to your project:

<dependency>
    <groupId>org.jboss.as</groupId>
    <artifactId>jboss-as-controller-client</artifactId>
    <version>7.2.0.Final</version>
</dependency>