1 /* 2 * Copyright (c) 2000, 2017 Oracle and/or its affiliates. All rights reserved. 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Distribution License v. 1.0, which is available at 6 * http://www.eclipse.org/org/documents/edl-v10.php. 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 */ 10 11 import java.util.Enumeration; 12 import java.util.Properties; 13 import javax.jms.*; 14 15 /** 16 * The BrokerMetrics example is a JMS application that monitors the 17 * Oracle GlassFish(tm) Server Message Queue broker. It does so by subscribing to a 18 * topic named 'mq.metrics.broker'. The messages that arrive contain 19 * Broker metric information such as number of messages flowing in/out 20 * of the broker, size in bytes of messages flowing in/out etc. 21 * 22 * This application also shows how to use the timestamp in each metric 23 * message to calculate rates e.g. rate at which messages are flowing 24 * into the broker. 25 * 26 * This application takes the following arguments: 27 * -m ttl Show totals e.g. total/accumulative number of msgs 28 * that flowed in/out of the broker. This is the 29 * default. 30 * -m rts Show rates e.g. rate of mesasge flow in/out of 31 * broker. 32 * 33 * By default BrokerMetrics will connect to the broker running on localhost:7676. 34 * You can use -DimqAddressList attribute to change the host, port and 35 * transport: 36 * 37 * java -DimqAddressList=mq://<host>:<port>/jms DestListMetrics 38 * 39 */ 40 public class BrokerMetrics implements MessageListener { 41 ConnectionFactory metricConnectionFactory; 42 Connection metricConnection; 43 Session metricSession; 44 MessageConsumer metricConsumer; 45 Topic metricTopic; 46 MetricsPrinter mp; 47 int rowsPrinted = 0; 48 boolean showTotals = true; 49 MapMessage previous = null; 50 main(String args[])51 public static void main(String args[]) { 52 boolean totals = true; 53 54 for (int i = 0; i < args.length; ++i) { 55 if (args[i].equals("-m")) { 56 String type = args[i+1]; 57 58 if (type.equals("ttl")) { 59 totals = true; 60 } else if (type.equals("rts")) { 61 totals = false; 62 } 63 } 64 } 65 BrokerMetrics bm = new BrokerMetrics(); 66 67 bm.showTotals = totals; 68 bm.initPrinter(); 69 bm.initJMS(); 70 bm.subscribeToMetric(); 71 } 72 73 /* 74 * Initializes the class that does the printing, MetricsPrinter. 75 * See the MetricsPrinter class for details. 76 */ initPrinter()77 private void initPrinter() { 78 String oneRow[] = new String[ 8 ]; 79 int span[] = new int[ 8 ]; 80 int i = 0; 81 82 mp = new MetricsPrinter(8, 2, "-", MetricsPrinter.CENTER); 83 mp.setTitleAlign(MetricsPrinter.CENTER); 84 85 span[i++] = 2; 86 span[i++] = 0; 87 span[i++] = 2; 88 span[i++] = 0; 89 span[i++] = 2; 90 span[i++] = 0; 91 span[i++] = 2; 92 span[i++] = 0; 93 94 i = 0; 95 if (showTotals) { 96 oneRow[i++] = "Msgs"; 97 oneRow[i++] = ""; 98 oneRow[i++] = "Msg Bytes"; 99 oneRow[i++] = ""; 100 oneRow[i++] = "Pkts"; 101 oneRow[i++] = ""; 102 oneRow[i++] = "Pkt Bytes"; 103 oneRow[i++] = ""; 104 } else { 105 oneRow[i++] = "Msgs/sec"; 106 oneRow[i++] = ""; 107 oneRow[i++] = "Msg Bytes/sec"; 108 oneRow[i++] = ""; 109 oneRow[i++] = "Pkts/sec"; 110 oneRow[i++] = ""; 111 oneRow[i++] = "Pkt Bytes/sec"; 112 oneRow[i++] = ""; 113 } 114 mp.addTitle(oneRow, span); 115 116 i = 0; 117 oneRow[i++] = "In"; 118 oneRow[i++] = "Out"; 119 oneRow[i++] = "In"; 120 oneRow[i++] = "Out"; 121 oneRow[i++] = "In"; 122 oneRow[i++] = "Out"; 123 oneRow[i++] = "In"; 124 oneRow[i++] = "Out"; 125 126 mp.addTitle(oneRow); 127 } 128 129 /** 130 * Create the Connection and Session etc. 131 */ initJMS()132 public void initJMS() { 133 try { 134 metricConnectionFactory = new com.sun.messaging.ConnectionFactory(); 135 metricConnection = metricConnectionFactory.createConnection(); 136 metricConnection.start(); 137 138 // creating Session 139 // Transaction Mode: None 140 // Acknowledge Mode: Automatic 141 metricSession = metricConnection.createSession(false, 142 Session.AUTO_ACKNOWLEDGE); 143 } catch(Exception e) { 144 System.err.println("Cannot create metric connection or session: " 145 + e.getMessage()); 146 e.printStackTrace(); 147 System.exit(1); 148 } 149 } 150 subscribeToMetric()151 public void subscribeToMetric() { 152 try { 153 metricTopic = metricSession.createTopic("mq.metrics.broker"); 154 155 metricConsumer = metricSession.createConsumer(metricTopic); 156 metricConsumer.setMessageListener(this); 157 } catch(JMSException e) { 158 System.err.println("Cannot subscribe to metric topic: " 159 + e.getMessage()); 160 e.printStackTrace(); 161 System.exit(1); 162 } 163 } 164 165 /* 166 * When a metric message arrives 167 * - verify it's type 168 * - extract it's fields 169 * - print one row of output 170 */ onMessage(Message m)171 public void onMessage(Message m) { 172 try { 173 MapMessage mapMsg = (MapMessage)m; 174 String type = mapMsg.getStringProperty("type"); 175 176 if (type.equals("mq.metrics.broker")) { 177 if (showTotals) { 178 doTotals(mapMsg); 179 } else { 180 doRates(mapMsg); 181 } 182 183 } else { 184 System.err.println("Msg received: not broker metric type"); 185 } 186 } catch (Exception e) { 187 System.err.println("onMessage: Exception caught: " + e); 188 } 189 } 190 doTotals(MapMessage mapMsg)191 private void doTotals(MapMessage mapMsg) { 192 try { 193 String oneRow[] = new String[ 8 ]; 194 int i = 0; 195 196 /* 197 * Extract broker metrics 198 */ 199 oneRow[i++] = Long.toString(mapMsg.getLong("numMsgsIn")); 200 oneRow[i++] = Long.toString(mapMsg.getLong("numMsgsOut")); 201 oneRow[i++] = Long.toString(mapMsg.getLong("msgBytesIn")); 202 oneRow[i++] = Long.toString(mapMsg.getLong("msgBytesOut")); 203 oneRow[i++] = Long.toString(mapMsg.getLong("numPktsIn")); 204 oneRow[i++] = Long.toString(mapMsg.getLong("numPktsOut")); 205 oneRow[i++] = Long.toString(mapMsg.getLong("pktBytesIn")); 206 oneRow[i++] = Long.toString(mapMsg.getLong("pktBytesOut")); 207 208 mp.add(oneRow); 209 210 if ((rowsPrinted % 20) == 0) { 211 mp.print(); 212 } else { 213 mp.print(false); 214 } 215 216 rowsPrinted++; 217 218 mp.clear(); 219 } catch (Exception e) { 220 System.err.println("onMessage: Exception caught: " + e); 221 } 222 } 223 doRates(MapMessage mapMsg)224 private void doRates(MapMessage mapMsg) { 225 String oneRow[] = new String[ 8 ]; 226 int i = 0; 227 228 try { 229 if (previous == null) { 230 oneRow[i++] = "0"; 231 oneRow[i++] = "0"; 232 oneRow[i++] = "0"; 233 oneRow[i++] = "0"; 234 oneRow[i++] = "0"; 235 oneRow[i++] = "0"; 236 oneRow[i++] = "0"; 237 oneRow[i++] = "0"; 238 } else { 239 long prevVal, newVal, prevSecs, newSecs, tmp; 240 float secs; 241 242 prevSecs = previous.getLongProperty("timestamp"); 243 newSecs = mapMsg.getLongProperty("timestamp"); 244 secs = (float)(newSecs - prevSecs)/(float)1000; 245 246 oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "numMsgsIn")); 247 oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "numMsgsOut")); 248 oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "msgBytesIn")); 249 oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "msgBytesOut")); 250 oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "numPktsIn")); 251 oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "numPktsOut")); 252 oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "pktBytesIn")); 253 oneRow[i++] = Long.toString(getRate(previous, mapMsg, secs, "pktBytesOut")); 254 } 255 256 previous = mapMsg; 257 258 mp.add(oneRow); 259 260 if ((rowsPrinted % 20) == 0) { 261 mp.print(); 262 } else { 263 mp.print(false); 264 } 265 266 rowsPrinted++; 267 268 mp.clear(); 269 } catch (Exception e) { 270 System.err.println("onMessage: Exception caught: " + e); 271 e.printStackTrace(); 272 } 273 } 274 getRate(MapMessage previous, MapMessage mapMsg, float secs, String propName)275 private long getRate(MapMessage previous, MapMessage mapMsg, float secs, 276 String propName) throws JMSException { 277 278 long prevVal, newVal, prevSecs, newSecs, tmp; 279 280 prevVal = previous.getLong(propName); 281 newVal = mapMsg.getLong(propName); 282 283 tmp = (long)((newVal - prevVal)/secs); 284 285 return (tmp); 286 } 287 } 288