Apache ActiveMQ Monitoring Tutorial (original) (raw)

Apache ActiveMQ (AMQ) is an open source messaging server written in Java which implements JMS 1.1 specifications. In this example, I will explain how to monitor an AMQ server.

1. Introduction

Apache ActiveMQ (AMQ) is an open source messaging server written in Java which implements JMS 1.1 specifications. Most of the enterprise applications use AMQ as a building block for their MOM infrastructure, so it’s critical that the AMQ server functions as expected. In this example, I will explain how to monitor an AMQ server from these four aspects:

2. Monitor ActiveMQ JVM

AMQ is a JVM. Oracle provides free monitoring tools to monitor the JVM’s CPU, Memory and threads.

Open Source JVM monitor tools:

3. Monitor ActiveMQ Web Console

AMQ provides a web console (Ex: http://localhost:8161/admin/index.jsp) to enable users to administrate and monitor the AMQ. The administrator can check any queue which has no consumer or has large amounts of pending messages. AMQ also provides the XML feeds to retrieve the information from the queues. (Ex: http://localhost:8161/admin/xml/queues.jsp). Users can use a web application monitoring tool to monitor the web console index web page and the XML feed page.

Web application monitoring tools:

4. Monitor ActiveMQ File System

AMQ uses log4j to generate three log files under the data directory with the default settings.

The log file’s information and location can be changed by following these instructions. These log files grow as time goes by. Users can use a file system monitoring tool to monitor the disk space.

File system monitoring tools:

5. Monitor ActiveMQ Application

AMQ is a message broker which transfers the message from the sender to the receiver. Users monitor the AMQ broker to ensure that the messaging broker is in a healthy state.

AMQ broker monitoring tools:

6. Java Example

In this example, I will demonstrate how to build a simple Java scheduler application which monitors AMQ queues and then sends notifications when it detects a queue with no consumers or a large amount of pending messages.

6.1 Technologies used

The example code in this article was built and run using:

6.2 Data Model

AMQ provides a XML feeds to retrieve the information from the queues.

http://localhost:8161/admin/xml/queues.jsp

queueBrowse/test.queue?view=rss&feedType=atom_1.0 queueBrowse/test.queue?view=rss&feedType=rss_2.0

I create a ListOfActiveMqQueue to map to the root of the XML element queues.

ListOfActiveMqQueue.java

package jcg.demo.model;

import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "queues") public class ListOfActiveMqQueue { private List queue;

public List getQueue() {
    return queue;
}

public void setQueue(List queue) {
    this.queue = queue;
}

}

I create a ActiveMqQueue to map to the child element queue.

ActiveMqQueue.java

package jcg.demo.model;

import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="queue") @XmlAccessorType(XmlAccessType.FIELD) public class ActiveMqQueue {

@XmlAttribute
private String name;
private Stats stats;

public String getName() {
    return name;
}

public Stats getStats() {
    return stats;
}

public void setName(String name) {
    this.name = name;
}

public void setStats(Stats stats) {
    this.stats = stats;
}

}

I create a Stats to map to the child element stats.

Stats.java

package jcg.demo.model;

import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Stats {

@XmlAttribute
private Integer size;
@XmlAttribute
private int consumerCount;
@XmlAttribute
private int enqueueCount;
@XmlAttribute
private int dequeueCount;

public Integer getSize() {
    return size;
}

public int getConsumerCount() {
    return consumerCount;
}

public int getEnqueueCount() {
    return enqueueCount;
}

public int getDequeueCount() {
    return dequeueCount;
}

public void setSize(Integer size) {
    this.size = size;
}

public void setConsumerCount(int consumerCount) {
    this.consumerCount = consumerCount;
}

public void setEnqueueCount(int enqueueCount) {
    this.enqueueCount = enqueueCount;
}

public void setDequeueCount(int dequeueCount) {
    this.dequeueCount = dequeueCount;
}

}

6.3 Monitor Service

Create a monitor service which monitors the given AMQ server’s queues and invokes the NotificationService to send an email when it detects that the queue has no consumers or there is a queue with too many pending messages.

ActiveMQMonitorService.java

package jcg.demo.service;

import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection;

import jcg.demo.model.ActiveMqQueue; import jcg.demo.model.NotificationEmail; import jcg.demo.model.ListOfActiveMqQueue;

public class ActiveMQMonitorService {

private ActiveMqQueueTransformer transformer = new ActiveMqQueueTransformer();
private NotificationService notService = new NotificationService();

@SuppressWarnings("resource")
public void monitorAndNotify(String brokerUrl, String username, String password, int maxPendingMessageLimit) {
    System.out.println("monitorAndNotify starts for " + brokerUrl);
    NotificationEmail email = dummyEmail();
    InputStream xmlFeedData = readXmlFeeds(brokerUrl, username, password);

    ListOfActiveMqQueue activeMqXmlData = transformer.convertFromInputStream(xmlFeedData);
    if (activeMqXmlData != null) {
        for (ActiveMqQueue queue : activeMqXmlData.getQueue()) {
            if (queue.getStats().getConsumerCount() == 0) {				
                email.setSubject("Must check activeMQ, queue: " + queue.getName() + " has no consumer.");
                notService.sendEmail(email);
            }
            else{
                int pendingMessageCounts = queue.getStats().getSize() - queue.getStats().getEnqueueCount();
                if( pendingMessageCounts > maxPendingMessageLimit){
                    email.setSubject("Must check activeMQ, queue: " + queue.getName() + " has large pending message. ");
                    notService.sendEmail(email);
                }
            }
        }
    }	
    System.out.println("monitorAndNotify completes for " + brokerUrl);
}

private InputStream readXmlFeeds(String brokerUrl, String username, String password) {
    try {
        URL url = new URL(brokerUrl);
        URLConnection uc = url.openConnection();

        String userpass = username + ":" + password;
        String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes());

        uc.setRequestProperty("Authorization", basicAuth);

        return uc.getInputStream();

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

private NotificationEmail dummyEmail() {
    NotificationEmail noConsumerEmail = new NotificationEmail();
    noConsumerEmail.setFromAddress("monitorApp@noreply.com");
    noConsumerEmail.setToAddress("activeMQServerMonitorTeam@test.com");
    noConsumerEmail.setBody("test email body message");
    return noConsumerEmail;
}

}

6.4 Quartz Job

Create a Quartz job to monitor the AMQ server.

QuartzJob.java

package jcg.demo.scheduler.quartz2;

import java.time.LocalDateTime; import java.util.List;

import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException;

import jcg.demo.model.NotificationEmail; import jcg.demo.service.ActiveMQMonitorService; import jcg.demo.service.NotificationService;

/**

}

6.5 Monitor Application

Create a monitor application which runs every minutes to monitor the given AMQ server’s queues and sends notifications when it detects that the queue has no consumers or there is a queue with too many pending messages.

QuartzSchedulerApp.java

package jcg.demo.scheduler.quartz2;

import java.util.List;

import org.quartz.CronScheduleBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.Scheduler; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory;

/**

}

6.6 Monitor Application execution

Start the AMQ server locally ad then execute the monitor application.

Output

QuartzSchedulerApp main thread: main SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. DefaultQuartzScheduler_Worker-1: Run QuartzJob at 2017-12-28T14:15:00.058 monitorAndNotify starts for http://localhost:8161/admin/xml/queues.jsp NotificationService send email EmailNotification [ toAddress=activeMQServerMonitorTeam@test.com, subject=Must check activeMQ, queue: test.queue has no consumer., body=test email body message] monitorAndNotify completes for http://localhost:8161/admin/xml/queues.jsp DefaultQuartzScheduler_Worker-2: Run QuartzJob at 2017-12-28T14:16:00.002 monitorAndNotify starts for http://localhost:8161/admin/xml/queues.jsp NotificationService send email EmailNotification [ toAddress=activeMQServerMonitorTeam@test.com, subject=Must check activeMQ, queue: test.queue has no consumer., body=test email body message] monitorAndNotify completes for http://localhost:8161/admin/xml/queues.jsp

7. Summary

In this example, I outlined how to monitor an AMQ server from four aspects: JVM, AMQ web console, the data file system, and the message broker. I also built a simple Java monitor application to monitor the AMQ based on the web console. There are lots of monitoring tools in the market. Use your best judgement to pick the best monitoring tool for your business. Here are few items to consider when choosing a monitoring tool:

8. References

9. Download the Source Code

This example consists of a Quartz scheduler to monitor an AMQ server based on the web console queue data.

Photo of Mary Zheng

Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.