001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.management;
018    
019    import javax.jms.Destination;
020    import javax.jms.MessageConsumer;
021    import javax.jms.MessageProducer;
022    import javax.jms.Session;
023    
024    import org.apache.activemq.util.IndentPrinter;
025    import org.apache.commons.logging.Log;
026    import org.apache.commons.logging.LogFactory;
027    
028    /**
029     * Statistics for a JMS endpoint, typically a MessageProducer or MessageConsumer
030     * but this class can also be used to represent statistics on a
031     * {@link Destination} as well.
032     * 
033     * @version $Revision: 1.3 $
034     */
035    public class JMSEndpointStatsImpl extends StatsImpl {
036        private static final Log LOG = LogFactory.getLog(JMSEndpointStatsImpl.class);
037    
038        protected CountStatisticImpl messageCount;
039        protected CountStatisticImpl pendingMessageCount;
040        protected CountStatisticImpl expiredMessageCount;
041        protected TimeStatisticImpl messageWaitTime;
042        protected TimeStatisticImpl messageRateTime;
043    
044        /**
045         * This constructor is used to create statistics for a
046         * {@link MessageProducer} or {@link MessageConsumer} as it passes in a
047         * {@link Session} parent statistic.
048         * 
049         * @param sessionStats
050         */
051        public JMSEndpointStatsImpl(JMSSessionStatsImpl sessionStats) {
052            this();
053            setParent(messageCount, sessionStats.getMessageCount());
054            setParent(pendingMessageCount, sessionStats.getPendingMessageCount());
055            setParent(expiredMessageCount, sessionStats.getExpiredMessageCount());
056            setParent(messageWaitTime, sessionStats.getMessageWaitTime());
057            setParent(messageRateTime, sessionStats.getMessageRateTime());
058        }
059    
060        /**
061         * This constructor is typically used to create a statistics object for a
062         * {@link Destination}
063         */
064        public JMSEndpointStatsImpl() {
065            this(new CountStatisticImpl("messageCount", "Number of messages processed"), new CountStatisticImpl("pendingMessageCount", "Number of pending messages"),
066                 new CountStatisticImpl("expiredMessageCount", "Number of expired messages"),
067                 new TimeStatisticImpl("messageWaitTime", "Time spent by a message before being delivered"), new TimeStatisticImpl("messageRateTime",
068                                                                                                                                   "Time taken to process a message (thoughtput rate)"));
069        }
070    
071        public JMSEndpointStatsImpl(CountStatisticImpl messageCount, CountStatisticImpl pendingMessageCount, CountStatisticImpl expiredMessageCount, TimeStatisticImpl messageWaitTime,
072                                    TimeStatisticImpl messageRateTime) {
073            this.messageCount = messageCount;
074            this.pendingMessageCount = pendingMessageCount;
075            this.expiredMessageCount = expiredMessageCount;
076            this.messageWaitTime = messageWaitTime;
077            this.messageRateTime = messageRateTime;
078    
079            // lets add named stats
080            addStatistic("messageCount", messageCount);
081            addStatistic("pendingMessageCount", pendingMessageCount);
082            addStatistic("expiredMessageCount", expiredMessageCount);
083            addStatistic("messageWaitTime", messageWaitTime);
084            addStatistic("messageRateTime", messageRateTime);
085        }
086    
087        public synchronized void reset() {
088            super.reset();
089            messageCount.reset();
090            messageRateTime.reset();
091            pendingMessageCount.reset();
092            expiredMessageCount.reset();
093            messageWaitTime.reset();
094        }
095    
096        public CountStatisticImpl getMessageCount() {
097            return messageCount;
098        }
099    
100        public CountStatisticImpl getPendingMessageCount() {
101            return pendingMessageCount;
102        }
103    
104        public CountStatisticImpl getExpiredMessageCount() {
105            return expiredMessageCount;
106        }
107    
108        public TimeStatisticImpl getMessageRateTime() {
109            return messageRateTime;
110        }
111    
112        public TimeStatisticImpl getMessageWaitTime() {
113            return messageWaitTime;
114        }
115    
116        public String toString() {
117            StringBuffer buffer = new StringBuffer();
118            buffer.append(messageCount);
119            buffer.append(" ");
120            buffer.append(messageRateTime);
121            buffer.append(" ");
122            buffer.append(pendingMessageCount);
123            buffer.append(" ");
124            buffer.append(expiredMessageCount);
125            buffer.append(" ");
126            buffer.append(messageWaitTime);
127            return buffer.toString();
128        }
129    
130        public void onMessage() {
131            if (enabled) {
132                long start = messageCount.getLastSampleTime();
133                messageCount.increment();
134                long end = messageCount.getLastSampleTime();
135                messageRateTime.addTime(end - start);
136            }
137        }
138    
139        public void dump(IndentPrinter out) {
140            out.printIndent();
141            out.println(messageCount);
142            out.printIndent();
143            out.println(messageRateTime);
144            out.printIndent();
145            out.println(pendingMessageCount);
146            out.printIndent();
147            out.println(messageRateTime);
148            out.printIndent();
149            out.println(expiredMessageCount);
150            out.printIndent();
151            out.println(messageWaitTime);
152        }
153    
154        // Implementation methods
155        // -------------------------------------------------------------------------
156        protected void setParent(CountStatisticImpl child, CountStatisticImpl parent) {
157            if (child instanceof CountStatisticImpl && parent instanceof CountStatisticImpl) {
158                CountStatisticImpl c = (CountStatisticImpl)child;
159                c.setParent((CountStatisticImpl)parent);
160            } else {
161                LOG.warn("Cannot associate endpoint counters with session level counters as they are not both CountStatisticImpl clases. Endpoint: " + child + " session: " + parent);
162            }
163        }
164    
165        protected void setParent(TimeStatisticImpl child, TimeStatisticImpl parent) {
166            if (child instanceof TimeStatisticImpl && parent instanceof TimeStatisticImpl) {
167                TimeStatisticImpl c = (TimeStatisticImpl)child;
168                c.setParent((TimeStatisticImpl)parent);
169            } else {
170                LOG.warn("Cannot associate endpoint counters with session level counters as they are not both TimeStatisticImpl clases. Endpoint: " + child + " session: " + parent);
171            }
172        }
173    }