1 /***
2 *
3 * Copyright 2004 Protique Ltd
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.codehaus.activemq.management;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.codehaus.activemq.util.IndentPrinter;
23
24 import javax.jms.Destination;
25 import javax.jms.Message;
26 import javax.jms.MessageConsumer;
27 import javax.jms.MessageProducer;
28 import javax.jms.Session;
29 import javax.management.j2ee.statistics.CountStatistic;
30 import javax.management.j2ee.statistics.JMSEndpointStats;
31 import javax.management.j2ee.statistics.TimeStatistic;
32
33 /***
34 * Statistics for a JMS endpoint, typically a MessageProducer or MessageConsumer
35 * but this class can also be used to represent statistics on a {@link Destination} as well.
36 *
37 * @version $Revision: 1.9 $
38 */
39 public class JMSEndpointStatsImpl extends StatsImpl implements JMSEndpointStats {
40 private static final Log log = LogFactory.getLog(JMSEndpointStatsImpl.class);
41
42 protected CountStatisticImpl messageCount;
43 protected CountStatisticImpl pendingMessageCount;
44 protected CountStatisticImpl expiredMessageCount;
45 protected TimeStatistic messageWaitTime;
46 protected TimeStatisticImpl messageRateTime;
47
48 /***
49 * This constructor is used to create statistics for a
50 * {@link MessageProducer} or {@link MessageConsumer} as it passes in a
51 * {@link Session} parent statistic.
52 *
53 * @param sessionStats
54 */
55 public JMSEndpointStatsImpl(JMSSessionStatsImpl sessionStats) {
56 this();
57 setParent(messageCount, sessionStats.getMessageCount());
58 setParent(pendingMessageCount, sessionStats.getPendingMessageCount());
59 setParent(expiredMessageCount, sessionStats.getExpiredMessageCount());
60 setParent(messageWaitTime, sessionStats.getMessageWaitTime());
61 setParent(messageRateTime, sessionStats.getMessageRateTime());
62 }
63
64 /***
65 * This constructor is typically used to create a statistics object for a
66 * {@link Destination}
67 */
68 public JMSEndpointStatsImpl() {
69 this(new CountStatisticImpl("messageCount", "Number of messages processed"),
70 new CountStatisticImpl("pendingMessageCount", "Number of pending messages"),
71 new CountStatisticImpl("expiredMessageCount", "Number of expired messages"),
72 new TimeStatisticImpl("messageWaitTime", "Time spent by a message before being delivered"),
73 new TimeStatisticImpl("messageRateTime", "Time taken to process a message (thoughtput rate)"));
74 }
75
76 public JMSEndpointStatsImpl(CountStatisticImpl messageCount, CountStatisticImpl pendingMessageCount, CountStatisticImpl expiredMessageCount, TimeStatisticImpl messageWaitTime, TimeStatisticImpl messageRateTime) {
77 this.messageCount = messageCount;
78 this.pendingMessageCount = pendingMessageCount;
79 this.expiredMessageCount = expiredMessageCount;
80 this.messageWaitTime = messageWaitTime;
81 this.messageRateTime = messageRateTime;
82
83
84 addStatistic("messageCount", messageCount);
85 addStatistic("pendingMessageCount", pendingMessageCount);
86 addStatistic("expiredMessageCount", expiredMessageCount);
87 addStatistic("messageWaitTime", messageWaitTime);
88 addStatistic("messageRateTime", messageRateTime);
89 }
90
91 public CountStatistic getMessageCount() {
92 return messageCount;
93 }
94
95 public CountStatistic getPendingMessageCount() {
96 return pendingMessageCount;
97 }
98
99 public CountStatistic getExpiredMessageCount() {
100 return expiredMessageCount;
101 }
102
103 public TimeStatistic getMessageWaitTime() {
104 return messageWaitTime;
105 }
106
107 public String toString() {
108 StringBuffer buffer = new StringBuffer();
109 buffer.append(messageCount);
110 buffer.append(" ");
111 buffer.append(messageRateTime);
112 buffer.append(" ");
113 buffer.append(pendingMessageCount);
114 buffer.append(" ");
115 buffer.append(expiredMessageCount);
116 buffer.append(" ");
117 buffer.append(messageWaitTime);
118 return buffer.toString();
119 }
120
121 public void onMessage(Message message) {
122 long start = messageCount.getLastSampleTime();
123 messageCount.increment();
124 long end = messageCount.getLastSampleTime();
125 messageRateTime.addTime(end - start);
126 }
127
128 public void dump(IndentPrinter out) {
129 out.printIndent();
130 out.println(messageCount);
131 out.printIndent();
132 out.println(messageRateTime);
133 out.printIndent();
134 out.println(pendingMessageCount);
135 out.printIndent();
136 out.println(messageRateTime);
137 out.printIndent();
138 out.println(expiredMessageCount);
139 out.printIndent();
140 out.println(messageWaitTime);
141 }
142
143
144
145 protected void setParent(CountStatistic child, CountStatistic parent) {
146 if (child instanceof CountStatisticImpl && parent instanceof CountStatisticImpl) {
147 CountStatisticImpl c = (CountStatisticImpl) child;
148 c.setParent((CountStatisticImpl) parent);
149 }
150 else {
151 log.warn("Cannot associate endpoint counters with session level counters as they are not both CountStatisticImpl clases. Endpoint: " + child + " session: " + parent);
152 }
153 }
154
155 protected void setParent(TimeStatistic child, TimeStatistic parent) {
156 if (child instanceof TimeStatisticImpl && parent instanceof TimeStatisticImpl) {
157 TimeStatisticImpl c = (TimeStatisticImpl) child;
158 c.setParent((TimeStatisticImpl) parent);
159 }
160 else {
161 log.warn("Cannot associate endpoint counters with session level counters as they are not both TimeStatisticImpl clases. Endpoint: " + child + " session: " + parent);
162 }
163 }
164 }