<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html>
<head>
<title>ActiveMQ Artemis Message Counter Example</title>
<link rel="stylesheet" type="text/css" href="../common/common.css" />
<link rel="stylesheet" type="text/css" href="../common/prettify.css" />
<script type="text/javascript" src="../common/prettify.js"></script>
</head>
<body onload="prettyPrint()">
<h1>JMS Message Counter Example</h1>
<p>This example shows you how to use message counters to obtain message information for a JMS queue.</p>
<p>The example will show how to configure sampling of message counters.<br />
We will produce and consume 1 message from a queue. Interleaved with the JMS operation, we will retrieve the queue's message counters
at different times to display the metrics on the queue.
</p>
<h2>Example setup</h2>
<p>Message counter is configured in the server configuration file <a href="server0/broker.xml">broker.xml</a>:</p>
<pre class="prettyprint">
<code><message-counter-enabled>true</message-counter-enabled>
<message-counter-sample-period>2000</message-counter-sample-period>
<message-counter-max-day-history>2</message-counter-max-day-history></code>
</pre>
<p>By default, Message counter is not enabled (for performance reason). To enable them, set <code>message-counter-enabled</code> to <code>true</code>.<br />
Queues are sampled every 10 seconds by default. For this example we will reduce it to 2 seconds by setting <code>message-counter-sample-period</code> to <code>2000</code>.<br />
ActiveMQ Artemis holds in memory the message counters' history for a maximum number of days (10 by default). We can change the number of days the history is kept by setting
the <code>message-counter-max-day-history</code> parameter.</p>
<p>The sample period and the max day history parameters have a small impact on the performance of ActiveMQ Artemis (the resources taken to sample a queue are not available to the system's
normal use). You should set these parameters accordingly to the use and throughput of your messages.</p>
<h2>Example step-by-step</h2>
<p><i>To run the example, simply type <code>mvn verify -Pexample</code> from this directory</i></p>
<ol>
<li>First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get it's properties from the <code>client-jndi.properties</code> file in the directory <code>../common/config</code></li>
<pre class="prettyprint">
<code>InitialContext initialContext = getContext();</code>
</pre>
<li>We look up the JMS queue object from JNDI</li>
<pre class="prettyprint">
<code>Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");</code>
</pre>
<li>We look up the JMS connection factory object from JNDI</li>
<pre class="prettyprint">
<code>ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");</code>
</pre>
<li>We create a JMS connection, session and producer for the queue</li>
<pre class="prettyprint">
<code> connection = cf.createQueueConnection();
QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);</code>
</pre>
<li>We create and send a JMS text message</li>
<pre class="prettyprint">
<code>TextMessage message = session.createTextMessage("This is a text message");
producer.send(message);
System.out.println("Sent message: " + message.getText());</code>
</pre>
<li>We will now sleep a little bit to be sure the queue is sample. Since we have configure the sample period to be 2 seconds,
we will sleep for 3 seconds to be sure that a sample is taken</li>
<pre class="prettyprint">
<code>System.out.println("Sleep a little bit to have the queue sampled...");
Thread.sleep(3000);</code>
</pre>
<p>We now need to retrieve the message counters. They're available from the JMS Queue management resource. In this example, we
will retrieve them using JMX (see the <a href="../jmx/readme.html">JMX example</a> for a more complete description). You can also use JMS message to retrieve them (see the <a href="../management/readme.html">Management example</a> to
learn about managing ActiveMQ Artemis using JMS messages).</p>
<li>We retrieve the JMX MBean used to manage the JMS queue</li>
<pre class="prettyprint">
<code>ObjectName on = ObjectNameBuilder.DEFAULT.getJMSQueueObjectName(queue.getQueueName());
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), new HashMap());
MBeanServerConnection mbsc = connector.getMBeanServerConnection();
JMSQueueControl queueControl = (JMSQueueControl)MBeanServerInvocationHandler.newProxyInstance(mbsc,
on,
JMSQueueControl.class,
false);</code>
</pre>
<li>We retrieve the message counter and display them. MessageCounters are retrieved as <code>JSON Strings</code> for portability reason (whether
JMX is used for management or JMS messages). To make it simpler to use them in the code, there is a <code>MessageCounterInfo</code> data structure.</li>
<pre class="prettyprint">
<code>String counters = queueControl.listMessageCounter();
MessageCounterInfo messageCounter = MessageCounterInfo.fromJSON(counters);</code>>
</pre>
<li>We display the message counters</li>
<pre class="prettyprint">
<code>displayMessageCounter(messageCounter);</code>
</pre>
<p>The message counter contains a variety of metrics on the queue which is sampled (total messages added to the queue, current depth of the queue, deltas since the last sample, timestamp
of the last message added, timestamp of the last sample, etc.)</p>
<pre class="prettyprint">
<code>
private void displayMessageCounter(MessageCounterInfo counter)
{
System.out.format("%s (sample updated at %s)\n", counter.getName(), counter.getUdpateTimestamp());
System.out.format(" %s message(s) added to the queue (since last sample: %s)\n", counter.getCount(),
counter.getCountDelta());
System.out.format(" %s message(s) in the queue (since last sample: %s)\n", counter.getDepth(),
counter.getDepthDelta());
System.out.format(" last message added at %s\n\n", counter.getLastAddTimestamp());
}</code>
</pre>
<li>We sleep again to have the queue sampled</li>
<pre class="prettyprint">
<code>System.out.println("Sleep a little bit again...");
Thread.sleep(3000);</code>
</pre>
<li>We list the message counters again</li>
<pre class="prettyprint">
<code>counters = queueControl.listMessageCounter();
messageCounter = MessageCounterInfo.fromJSON(counters);
displayMessageCounter(messageCounter);</code>
</pre>
<p>We will now consume a message from the queue before listing a last time the message counters</p>
<li>We create a consumer for the queue</li>
<pre class="prettyprint">
<code>MessageConsumer consumer = session.createConsumer(queue);</code>
</pre>
<li>We start the connection to receive messages on the consumer</li>
<pre class="prettyprint">
<code>connection.start();</code>
</pre>
<li>We receive a message from the queue</li>
<pre class="prettyprint">
<code>TextMessage messageReceived = (TextMessage)consumer.receive(5000);
System.out.format("Received message: %s\n\n", messageReceived.getText());</code>
</pre>
<li>We sleep one last time to have the queue sampled</li>
<pre class="prettyprint">
<code>System.out.println("Sleep a little bit one last time...");
Thread.sleep(3000);</code>
</pre>
<li>We list the message counters a final time (this time with no message in the queue)</li>
<pre class="prettyprint">
<code>counters = queueControl.listMessageCounter();
messageCounter = MessageCounterInfo.fromJSON(counters);
displayMessageCounter(messageCounter);</code>
</pre>
</p>
<li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li>
<pre class="prettyprint">
<code>finally
{
if (initialContext != null)
{
initialContext.close();
}
if (connection != null)
{
connection.close();
}
}</code>
</pre>
</ol>
<li>User Manual's <a href="../../../docs/user-manual/en/html_single/index.html#management.message-counters">Message Counters chapter</a></li>
<li><a href="../../../docs/api/org/jboss/messaging/core/management/MessageCounterInfo.html">MessageCounterInfo</a> is a helper class used
to create a MessageCounterInfo object from the JSON String which represents message counters</li>
</body>
</html>