Thursday, October 15, 2009

Query Statistics for Apache ActiveMQ

Apache ActiveMQ has extensive support for JMX, but if you want to find out the running state of ActiveMQ from your application or from the one of the number of cross-language clients - your options are a bit limited.

ActiveMQ supports Broker plugins, which allows the default functionality to be extended, and new with version 5.3 of Apache ActiveMQ is a Statistics plugin, which enables statistics about the running broker, or Queues and Topics to be queried. To configure ActiveMQ to use the statistics plugin - just add the following to the ActiveMQ XML configuration:
...
<plugins>
<statisticsBrokerPlugin/>
</plugins>

The statistics plugin looks for messages sent to particular destinations. To query the running statistics of a the message broker, send an empty message to a Destination (Queue or Topic) named ActiveMQ.Statistics.Broker, and set the replyTo (jmsReplyTo if using JMS) field with the Destination you want to receive the result on. The statistics plugin will send a MapMessage filled with the statistics for the running ActiveMQ broker - e.g.

Queue replyTo = session.createTemporaryQueue();
MessageConsumer consumer = session.createConsumer(replyTo);


Queue query = session.createQueue("ActiveMQ.Statistics.Broker");
MessageProducer producer = session.createProducer(query);
Message msg = session.createMessage();
msg.setJMSReplyTo(replyTo);
producer.send(msg);


MapMessage reply = (MapMessage) consumer.receive();


for (Enumeration e = reply.getMapNames();e.hasMoreElements();) {
String name = e.nextElement().toString();
System.err.println(name+"="+reply.getObject(name));
}

You should see output like this:
vm=vm://localhost
memoryUsage=0
storeUsage=3330
tempPercentUsage=0
ssl=
openwire=tcp://localhost:50059
brokerId=ID:bigmac-50057-1253605065511-0:0
consumerCount=2
brokerName=localhost
expiredCount=0
dispatchCount=1
maxEnqueueTime=5.0
storePercentUsage=0
dequeueCount=0
inflightCount=1
messagesCached=0
tempLimit=107374182400
averageEnqueueTime=5.0
stomp+ssl=
memoryPercentUsage=0
size=10
tempUsage=0
producerCount=1
minEnqueueTime=5.0
dataDirectory=/Users/rajdavies/dev/projects/activemq/activemq-core/activemq-data
enqueueCount=10
stomp=
storeLimit=107374182400
memoryLimit=67108864



Similarly, if you want to query the statistics on a Destination, send a message to the Destination name, prepended with ActiveMQ.Statistics.Destination. For example, to retrieve the statistics on a Queue named test.foo send an empty message to the Queue ActiveMQ.Statistics.DestinationTest.Foo.
e.g.


Queue replyTo = session.createTemporaryQueue();
 MessageConsumer consumer = session.createConsumer(replyTo);
 Queue testQueue = session.createQueue("Test.Queue");
 MessageProducer producer = session.createProducer(null);
 Queue query = session.createQueue("
ActiveMQ.Statistics.Destination" +    testQueue.getQueueName());

 Message msg = session.createMessage();
       
  producer.send(testQueue,msg)
   msg.setJMSReplyTo(replyTo);
   producer.send(query,msg);
  MapMessage reply = (MapMessage) consumer.receive();
  assertNotNull(reply);
  assertTrue(reply.getMapNames().hasMoreElements());
       
  for (Enumeration e = reply.getMapNames();e.hasMoreElements();) {
            String name = e.nextElement().toString();
            System.err.println(name+"="+reply.getObject(name));
   }

       
You should see:



memoryUsage=0
dequeueCount=0
inflightCount=0
messagesCached=0
averageEnqueueTime=0.0
destinationName=queue://Test.Queue
size=1
memoryPercentUsage=0
producerCount=0
consumerCount=0
minEnqueueTime=0.0
maxEnqueueTime=0.0
dispatchCount=0
expiredCount=0
enqueueCount=1
memoryLimit=67108864


You can also use wildcards too, and receive a separate message for every destination matched.










7 comments:

Anonymous said...

That's really nice I wonder if I can access this stats over Stomp, would be much lighter to integrate into monitoring tools that way.

Any ideas? Have tried a few things without luck so far.

id said...

Using the message transformation extension for object and map messages, it is possible - I have implemented it in a Stomp client library for Delphi now. See http://mikejustin.wordpress.com/2010/03/11/query-statistics-for-apache-activemq-with-delphi/

Volcane said...

I have some sample code in Ruby up at http://github.com/ripienaar/monitoring-scripts/tree/master/activemq/ that speaks to this plugin via Stomp. Also converts the Java Maps to ruby Hashes.

Seeing some weird consumer counts though, always going up eventhough consumers have disconnected. Only in networks of brokers

P!cO said...

I use it from a PHP script over STOMP and it works just fine for my integration with Cacti.

But i don't know the unit use on the returned values like storeUsage or averageEnqueueTime for example.

Any ideas about the units used?

Chilla Sridhar said...

The above code is creating statistics queue which is not temporary. I dont see any point in existance of this queue after the client connection exits. Will it get destroyed automatically at broker exit?.

Chilla Sridhar said...

The above code is creating statistics queue. When will it get destroyed ? I dont see any point in having this queue on broker after client connection exits.

Chilla Sridhar said...

At what point does the statistics queue gets destroyed ? I dont see any point in having this queue after client connection is terminated.