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 */
017package org.apache.activemq.management;
018
019import javax.jms.Destination;
020import javax.jms.MessageConsumer;
021import javax.jms.MessageProducer;
022import javax.jms.Session;
023
024import org.apache.activemq.util.IndentPrinter;
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
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 * 
034 */
035public class JMSEndpointStatsImpl extends StatsImpl {
036    private static final Logger LOG = LoggerFactory.getLogger(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    @Override
140    public void setEnabled(boolean enabled) {
141        super.setEnabled(enabled);
142        messageCount.setEnabled(enabled);
143        messageRateTime.setEnabled(enabled);
144        pendingMessageCount.setEnabled(enabled);
145        expiredMessageCount.setEnabled(enabled);
146        messageWaitTime.setEnabled(enabled);
147    }
148
149    public void dump(IndentPrinter out) {
150        out.printIndent();
151        out.println(messageCount);
152        out.printIndent();
153        out.println(messageRateTime);
154        out.printIndent();
155        out.println(pendingMessageCount);
156        out.printIndent();
157        out.println(messageRateTime);
158        out.printIndent();
159        out.println(expiredMessageCount);
160        out.printIndent();
161        out.println(messageWaitTime);
162    }
163
164    // Implementation methods
165    // -------------------------------------------------------------------------
166    protected void setParent(CountStatisticImpl child, CountStatisticImpl parent) {
167        if (child instanceof CountStatisticImpl && parent instanceof CountStatisticImpl) {
168            CountStatisticImpl c = (CountStatisticImpl)child;
169            c.setParent((CountStatisticImpl)parent);
170        } else {
171            LOG.warn("Cannot associate endpoint counters with session level counters as they are not both CountStatisticImpl clases. Endpoint: " + child + " session: " + parent);
172        }
173    }
174
175    protected void setParent(TimeStatisticImpl child, TimeStatisticImpl parent) {
176        if (child instanceof TimeStatisticImpl && parent instanceof TimeStatisticImpl) {
177            TimeStatisticImpl c = (TimeStatisticImpl)child;
178            c.setParent((TimeStatisticImpl)parent);
179        } else {
180            LOG.warn("Cannot associate endpoint counters with session level counters as they are not both TimeStatisticImpl clases. Endpoint: " + child + " session: " + parent);
181        }
182    }
183}