In this recipe we will look at how you can monitor activity in ActiveMQ Broker using the JMS API and the broker's built-in Advisory Message feature. Advisory messages from the broker allow your application to monitor events on the broker such as:
Connections, consumers, and producers starting and stopping
Temporary destinations being created and destroyed
Messages expiring on topics and queues
In this recipe we will use two examples. The first example is named advisory-generator, which will cause the broker to produce some advisory messages. The second one is named advisory-consumer, which demonstrates how we can implement those broker advisories.
To run the sample for this recipe you will need to perform the following steps:
Open a terminal and start a broker.
Open a second terminal, change the path to the directory where advisory-consumer is located, and run it by typing
mvn compile exec:java
(you can shut it down by pressing Ctrl + C when done or you can allow it to stop on its own after 10 minutes).Open a third terminal and change the path to the directory where advisory-generator is located and run the example by typing
mvn compile exec:java
(the sample will shut down on its own after a few minutes).
On the terminal where you started the example named advisory-consumer, you will see output like the following, indicating that the application is receiving advisory messages from the broker:
Starting Advisory Consumer example now... New Producer Advisory, Producer Count: 1 New Producer Advisory, Producer Count: 5 New Producer Advisory, Producer Count: 5 New Producer Advisory, Producer Count: 5 New Producer Advisory, Producer Count: 2 New Consumer Advisory, Consumer Count: 1 New Producer Advisory, Producer Count: 1 New Consumer Advisory, Consumer Count: 0 New Producer Advisory, Producer Count: 0 Finished running the Advisory Consumer example.
The advisory source application runs without generating much output as it's just used here to create some activity on the broker.
ActiveMQ Broker generates advisory messages for a number of different events that occur on the broker. Your client applications can subscribe to special topics where the events are sent in order to monitor activity on the broker. The advisory messages are just simple JMS message objects that can have some message properties set to provide helpful event-related information.
Our advisory-consumer example listens for events (related to MessageProducer
and MessageConsumer
) being added and removed from the broker for a particular destination; in this example we are watching the queue named MyQueue
. Let's take a look at the code for the sample application:
public class AdvisoryConsumerApp implements MessageListener { private final String connectionUri = "tcp://localhost:61616"; private ActiveMQConnectionFactory connectionFactory; private Connection connection; private Session session; private Destination destination; private MessageConsumer advisoryConsumer; private Destination monitored; public void before() throws Exception { connectionFactory = new ActiveMQConnectionFactory(connectionUri); connection = connectionFactory.createConnection(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); monitored = session.createQueue("MyQueue"); destination = session.createTopic( AdvisorySupport.getConsumerAdvisoryTopic(monitored).getPhysicalName() + "," + AdvisorySupport.getProducerAdvisoryTopic(monitored).getPhysicalName()); advisoryConsumer = session.createConsumer(destination); advisoryConsumer.setMessageListener(this); connection.start(); } public void onMessage(Message message) { try { Destination source = message.getJMSDestination(); if (source.equals(AdvisorySupport.getConsumerAdvisoryTopic(monitored))) { int consumerCount = message.getIntProperty("consumerCount"); System.out.println("New Consumer Advisory, Consumer Count: " + consumerCount); } else if (source.equals(AdvisorySupport.getProducerAdvisoryTopic(monitored))) { int producerCount = message.getIntProperty("producerCount"); System.out.println("New Producer Advisory, Producer Count: " + producerCount); } } catch (JMSException e) { } } }
In order to receive advisory messages from the broker, our sample application subscribes to two different topics on the broker. The topics subscribed to are those special advisory topics that were mentioned earlier, and the ActiveMQ client library provides a convenience class named AdvisorySupport
for fetching the various advisory topics available.
We use another ActiveMQ feature in this example to save some typing by subscribing to two destinations with one consumer. The destination passed to the createConsumer
method is referred to as Composite Destination, which simply means we concatenated two destination names with a comma. We can add even more destinations if we want to.
In our sample application's onMessage
callback method, we determine which advisory message we are receiving by examining the JMSDestination
message property. Once we know which advisory message we are dealing with, we can find the consumer and producer counts for our monitored destination by accessing the consumerCount
property that the broker adds to the advisory message.
Advisory messages are enabled by default on the broker, although only a subset of the complete set will be generated by default. The complete list of advisory messages can be found on the ActiveMQ website, http://activemq.apache.org/advisory-message.html, along with information on the specific properties and contents of each advisory message.
Having the advisory messages enabled does generate a small amount of overhead on the network though, so they can be disabled in the broker's XML configuration file. In order to turn off advisory messages, we will add the advisorySupport="false"
option to the broker
XML element in the configuration file. It will look something like this:
<broker advisorySupport="false">...