Monitoring queue statistics in MQ
30 April, 2007 – 4:55 pmWhen load testing MQ you are no doubt going to need to be able to monitor queue statistics in terms of how many messages have been enqueued and dequeued within a given timeframe. You can use native runmqsc commands to query queues in order to find current queue depths but this is just a snapshot in time. In order to be able to monitor how many messages have been or gone, you need to sample the queue over time. Here is a good synopsis of options…
A good way to achieve this is my using the PCF support package provided by IBM.
The WebSphere MQ Programmable Command Formats (PCF) provide the capability to perform administration tasks on a queue manager by sending and receiving WebSphere MQ messages of a special format. PCF request messages are sent to the queue manager’s command queue, where they are processed by the command server and replies returned to the designated reply-to queue.
This SupportPac contains a set of Java classes representing PCF header structures as well as an agent that can be used to simplify the task of communicating with a target queue manager and thus enable the use of WebSphere MQ Programmable Command Formats for queue manager administration.
Using a simple java object as documented in sample code, you can query queue stats of your choice. My implementation simply prints out the queue you are connected to, along with enqueue, dequeue and total queue size stats over an arbitrary time frame (eg. last 2 seconds). This can easily be called from a simple shell script.
ResetQStats.java
/**
* Reset MQ Queue Statistics (ResetQStats)
*
* Compile : javac -classpath com.ibm.mq.jar:connector.jar:jta.jar:com.ibm.mq.pcf-6.0.jar ResetQStats.java
* Package : jar cfm ResetQStats.jar ResetQStats.MF *.class
* Execute : java -cp com.ibm.mq.jar:connector.jar:jta.jar:com.ibm.mq.pcf-6.0.jar:ResetQStats.jar ResetQStats [options]
* Usage : ResetQStats [options]
* Options :
host MQ hostname eg. 127.0.0.1
port MQ port eg. 1415
channel MQ channel eg. CHANNEL_NAME
queue MQ queue eg. QUEUE_NAME
*
* Last edited : 6 Mar 07 14.00
* Author : Tim Koopmans
**/
import java.io.*;
import com.ibm.mq.*;
import com.ibm.mq.pcf.*;
public class ResetQStats
{
final public static String copyright =
"Copyright (c) IBM Corp. 2005 All rights reserved.";
public static void main (String [] args)
{
PCFAgent agent;
PCFParameter [] parameters = { new MQCFST (CMQC.MQCA_Q_NAME,args [3]) };
MQMessage [] responses;
MQCFH cfh;
PCFParameter p;
try
{
// Connect a PCFAgent to the specified queue manager
if (args.length == 1)
{
agent = new PCFAgent (args [0]);
}
else
{
agent = new PCFAgent (args [0], Integer.parseInt (args [1]), args [2]);
}
// Use the agent to send the request
responses = agent.send (CMQCFC.MQCMD_RESET_Q_STATS, parameters);
cfh = new MQCFH (responses [0]);
if (cfh.reason == 0)
{
//System.out.println ("Queue Statistics:");
for (int i = 0; i < cfh.parameterCount; i++)
{
// Walk through the returned attributes
p = PCFParameter.nextParameter (responses [0]);
int parm = p.getParameter();
switch (parm)
{
case CMQC.MQCA_Q_NAME:
//Queue Name
break;
case CMQC.MQIA_TIME_SINCE_RESET:
//TimeSinceReset t(sec)
break;
case CMQC.MQIA_MSG_ENQ_COUNT:
//MsgEnqCount ++
break;
case CMQC.MQIA_MSG_DEQ_COUNT:
//MsgDeqCount -- break;
case CMQC.MQIA_HIGH_Q_DEPTH:
//HighQDepth (total)
break;
}
System.out.print(" \t" + p.getValue ());
}
System.out.print("\n");
}
else
{
System.out.println ("PCF error:\n" + cfh);
// Walk through the returned parameters describing the error
for (int i = 0; i < cfh.parameterCount; i++)
{
System.out.println (PCFParameter.nextParameter (responses [0]));
}
}
// Disconnect
agent.disconnect ();
}
catch (ArrayIndexOutOfBoundsException abe)
{
System.out.println ("Usage: \n" +
"\tjava ResetQStats queue-manager\n" +
"\tjava ResetQStats host port svrconn-channel");
}
catch (NumberFormatException nfe)
{
System.out.println ("Invalid port: " + args [1]);
System.out.println ("Usage: \n" +
"\tjava ResetQStats queue-manager\n" +
"\tjava ResetQStats host port svrconn-channel");
}
catch (MQException mqe)
{
System.err.println (mqe);
}
catch (IOException ioe)
{
System.err.println (ioe);
}
}
}
Simple Shell Script
#~/bin/sh
javac -classpath $HOME/harness/CDE/com.ibm.mq.jar:$HOME/harness/CDE/connector.jar:$HOME/harness/CDE/jta.jar:/home/strata/d281447/harness/CDE/com.ibm.mq.pcf-6.0.jar $HOME/harness/CDE/ResetQStats.java
cd $HOME/harness/CDE
jar cfm ResetQStats.jar ResetQStats.MF *.class
rm $HOME/harness/CDE/*.class
cd $HOME/harness/CDE
printf "\tQueue Name\t\t\t\t\t\t++ \t-- \tdepth \tsecs\n"
duration=$2 #duration in seconds
sampleRate=$3 #sample every n seconds
i="1"
while [ $i -le $duration ]
do
java -cp com.ibm.mq.jar:connector.jar:jta.jar:com.ibm.mq.pcf-6.0.jar:ResetQStats.jar ResetQStats 127.0.0.1 1415 CHANNEL $1
sleep $sampleRate
i=`expr $i + 1`
done
printf "\n"








