Skip to content

Instantly share code, notes, and snippets.

@ibmmqmet
Last active October 6, 2022 06:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ibmmqmet/e9426b696fa27d0962755f819f3000ee to your computer and use it in GitHub Desktop.
Save ibmmqmet/e9426b696fa27d0962755f819f3000ee to your computer and use it in GitHub Desktop.
Basic MQ Queue Rate Monitoring - see https://marketaylor.synology.me/?p=1353

This gist shows how a few simple scripts can be chained together to create very basic MQ monitor that lists puts/sec in a table.

# Use MQ Statistics Events to calculate msg/sec rates for queues.
# Define a function to truncate floating point numbers to 2 places
def roundTo2: .*100.0|round/100.0;
# Filter all events to just process those with queue stats
select(.eventData.queueStatisticsData !=null) |
.eventData.queueMgrName as $qMgr |
# Extract time stamps and convert to epoch format in seconds
.eventData.startDate as $startDate |
.eventData.startTime as $startTime |
($startDate + " " + $startTime | strptime("%Y-%m-%d %H.%M.%S") | mktime) as $startEpoch |
.eventData.endDate as $endDate |
.eventData.endTime as $endTime |
($endDate + " " + $endTime | strptime("%Y-%m-%d %H.%M.%S") | mktime) as $endEpoch |
# Extract the PUT metrics and print along with the duration
# Duration should match (give-or-take a second or two) the
# qmgr's STATINT value (also given in seconds)
#
# Also print out the start time for a bit of sanity checking.
# We don't show the date here; it's just nice to see a timestamp moving in a readable format).
.eventData.queueStatisticsData[] |
(.puts[0] + .puts[1] + .put1s[0] + .put1s[1]) as $putTotal |
# The "+0.0" converts each side into floats so we get non-integer rates.
(($putTotal + 0.0)/ (($endEpoch - $startEpoch) + 0.0)) as $rate |
{
periodStart : $startEpoch ,
periodEnd : $endEpoch,
duration : ($endEpoch - $startEpoch),
startTime : $startTime,
queueMgr:$qMgr,
queue:.queueName,
putNP:(.puts[0] + .put1s[0]),
putP: (.puts[1] + .put1s[1]),
putTotal: $putTotal,
rate: $rate | roundTo2
}
# This final section might be optional but it further simplifies the
# output to just the 3 elements you might need to display current state
| [ .periodStart, .queue, .rate ]
#!/bin/bash
#
QM=QM1
. setmqenv -m $QM -k
# Use stdbuf to ensure output from amqsevt is unbuffered and printed as soon as available.
# The --unbuffered flag to jq does something similar
stdbuf -o0 /opt/mqm/samp/bin/amqsevt -m $QM -q SYSTEM.ADMIN.STATISTICS.QUEUE -o json |\
jq -f statsCount.jq -c --unbuffered |\
table.sh $QM
#!/bin/bash
qMgr="$1"
typeset -A metrics # Declare an associative array
oldStart=""
echo "Waiting for input ..."
#The output from the jq script looks something like:
# [12345678,SYSTEM.DEFAULT.LOCAL.QUEUE,1.23]
# so we need to do some conversions to extract the fields.
while read line
do
line2=`echo $line | sed "s/\[//g;s/]//g;s/\"//g"`
# Make sure the variables are set here - in bash, pipes are subshells so
# can't set variables in the main function. Meaning "echo 1 2 3 | read x y z" doesn't
# work as hoped. The <() syntax does what we need though.
IFS="," read start queue rate < <(echo "$line2")
# If we start reading a new set of metrics then display the
# previous set and clear out the array. There's no easy "read a batch of queues"
# from the JSON or event message output, so we use the timestamp as the discriminator.
if [ "$start" != "$oldStart" ]
then
# Is the array empty?
len=${#metrics[@]}
if [ $len != 0 ]
then
tput clear
echo "Metrics collected for $qMgr at `date`"
echo
printf "%-48.48s %s\n" "Queue" "Puts/Sec"
printf "%-48.48s %s\n" "-----" "--------"
# Find all the queue names and sort them ready for printing
for key in "${!metrics[@]}"
do
echo $key
done | sort |\
while read queue
do
printf "%-48.48s %.2f\n" $queue ${metrics["$queue"]}
done
# Empty the array for next time round - can't do it inside the "while" loop
for key in "${!metrics[@]}"
do
unset metrics["$key"]
done
echo "--------------"
fi
oldStart=$start
else
metrics["$queue"]=$rate
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment