How to monitor WildFly 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 article that discuses how to query WildFly resources using 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.

Overview of DMR API

Management resources expose information about their state as attributes. Attributes have string name, and a value of type org.jboss.dmr.ModelNode (or: for the CLI, the text representation of a ModelNode; for HTTP API, the JSON representation of a ModelNode.)unning out of JDBC Connections, for example.

The simplest way to access Management resources is via the CLI. For example, you can collect 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 monitor this attribute you can either create a shell script that iterates over the above command or you can access it programmatically using the DMR API.

Accessing Model Resources with the DMR API

In this simple EJB timer we will show how to access a Model attribute using 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>
Found the article helpful? if so please follow us on Socials