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.camel.management.mbean;
018    
019    import java.util.Date;
020    
021    import org.apache.camel.management.PerformanceCounter;
022    import org.apache.camel.spi.ManagementStrategy;
023    import org.fusesource.commons.management.Statistic;
024    import org.springframework.jmx.export.annotation.ManagedAttribute;
025    import org.springframework.jmx.export.annotation.ManagedOperation;
026    import org.springframework.jmx.export.annotation.ManagedResource;
027    
028    @ManagedResource(description = "PerformanceCounter")
029    public abstract class ManagedPerformanceCounter extends ManagedCounter implements PerformanceCounter {
030    
031        private Statistic exchangesCompleted;
032        private Statistic exchangesFailed;
033        private Statistic minProcessingTime;
034        private Statistic maxProcessingTime;
035        private Statistic totalProcessingTime;
036        private Statistic lastProcessingTime;
037        private Statistic meanProcessingTime;
038        private Statistic firstExchangeCompletedTimestamp;
039        private Statistic firstExchangeFailureTimestamp;
040        private Statistic lastExchangeCompletedTimestamp;
041        private Statistic lastExchangeFailureTimestamp;
042        private boolean statisticsEnabled = true;
043    
044        public void init(ManagementStrategy strategy) {
045            super.init(strategy);
046            this.exchangesCompleted = strategy.createStatistic("org.apache.camel.exchangesCompleted", this, Statistic.UpdateMode.COUNTER);
047            this.exchangesFailed = strategy.createStatistic("org.apache.camel.exchangesFailed", this, Statistic.UpdateMode.COUNTER);
048            this.minProcessingTime = strategy.createStatistic("org.apache.camel.minimumProcessingTime", this, Statistic.UpdateMode.MINIMUM);
049            this.maxProcessingTime = strategy.createStatistic("org.apache.camel.maximumProcessingTime", this, Statistic.UpdateMode.MAXIMUM);
050            this.totalProcessingTime = strategy.createStatistic("org.apache.camel.totalProcessingTime", this, Statistic.UpdateMode.COUNTER);
051            this.lastProcessingTime = strategy.createStatistic("org.apache.camel.lastProcessingTime", this, Statistic.UpdateMode.VALUE);
052            this.meanProcessingTime = strategy.createStatistic("org.apache.camel.meanProcessingTime", this, Statistic.UpdateMode.VALUE);
053    
054            this.firstExchangeCompletedTimestamp = strategy.createStatistic("org.apache.camel.firstExchangeCompletedTimestamp", this, Statistic.UpdateMode.VALUE);
055            this.firstExchangeFailureTimestamp = strategy.createStatistic("org.apache.camel.firstExchangeFailureTimestamp", this, Statistic.UpdateMode.VALUE);
056            this.lastExchangeCompletedTimestamp = strategy.createStatistic("org.apache.camel.lastExchangeCompletedTimestamp", this, Statistic.UpdateMode.VALUE);
057            this.lastExchangeFailureTimestamp = strategy.createStatistic("org.apache.camel.lastExchangeFailureTimestamp", this, Statistic.UpdateMode.VALUE);
058        }
059    
060        @Override
061        @ManagedOperation(description = "Reset counters")
062        public synchronized void reset() {
063            super.reset();
064            exchangesCompleted.reset();
065            exchangesFailed.reset();
066            minProcessingTime.reset();
067            maxProcessingTime.reset();
068            totalProcessingTime.reset();
069            lastProcessingTime.reset();
070            meanProcessingTime.reset();
071            firstExchangeCompletedTimestamp.reset();
072            firstExchangeFailureTimestamp.reset();
073            lastExchangeCompletedTimestamp.reset();
074            lastExchangeFailureTimestamp.reset();
075        }
076    
077        @ManagedAttribute(description = "Number of completed exchanges")
078        public long getExchangesCompleted() throws Exception {
079            return exchangesCompleted.getValue();
080        }
081    
082        @ManagedAttribute(description = "Number of failed exchanges")
083        public long getExchangesFailed() throws Exception {
084            return exchangesFailed.getValue();
085        }
086    
087        @ManagedAttribute(description = "Min Processing Time [milliseconds]")
088        public long getMinProcessingTime() throws Exception {
089            return minProcessingTime.getValue();
090        }
091    
092        @ManagedAttribute(description = "Mean Processing Time [milliseconds]")
093        public long getMeanProcessingTime() throws Exception {
094            return meanProcessingTime.getValue();
095        }
096    
097        @ManagedAttribute(description = "Max Processing Time [milliseconds]")
098        public long getMaxProcessingTime() throws Exception {
099            return maxProcessingTime.getValue();
100        }
101    
102        @ManagedAttribute(description = "Total Processing Time [milliseconds]")
103        public long getTotalProcessingTime() throws Exception {
104            return totalProcessingTime.getValue();
105        }
106    
107        @ManagedAttribute(description = "Last Processing Time [milliseconds]")
108        public long getLastProcessingTime() throws Exception {
109            return lastProcessingTime.getValue();
110        }
111    
112        @ManagedAttribute(description = "Last Exchange Completed Timestamp")
113        public Date getLastExchangeCompletedTimestamp() {
114            long value = lastExchangeCompletedTimestamp.getValue();
115            return value > 0 ? new Date(value) : null;
116        }
117    
118        @ManagedAttribute(description = "First Exchange Completed Timestamp")
119        public Date getFirstExchangeCompletedTimestamp() {
120            long value = firstExchangeCompletedTimestamp.getValue();
121            return value > 0 ? new Date(value) : null;
122        }
123    
124        @ManagedAttribute(description = "Last Exchange Failed Timestamp")
125        public Date getLastExchangeFailureTimestamp() {
126            long value = lastExchangeFailureTimestamp.getValue();
127            return value > 0 ? new Date(value) : null;
128        }
129    
130        @ManagedAttribute(description = "First Exchange Failed Timestamp")
131        public Date getFirstExchangeFailureTimestamp() {
132            long value = firstExchangeFailureTimestamp.getValue();
133            return value > 0 ? new Date(value) : null;
134        }
135    
136        @ManagedAttribute(description = "Statistics enabled")
137        public boolean isStatisticsEnabled() {
138            return statisticsEnabled;
139        }
140    
141        @ManagedAttribute(description = "Statistics enabled")
142        public void setStatisticsEnabled(boolean statisticsEnabled) {
143            this.statisticsEnabled = statisticsEnabled;
144        }
145    
146        /**
147         * This method is called when an exchange has been processed successfully.
148         * 
149         * @param time in milliseconds it spent on processing the exchange
150         */
151        public synchronized void completedExchange(long time) {
152            increment();
153            exchangesCompleted.increment();
154    
155            minProcessingTime.updateValue(time);
156            maxProcessingTime.updateValue(time);
157            totalProcessingTime.updateValue(time);
158            lastProcessingTime.updateValue(time);
159    
160            long now = new Date().getTime();
161            if (firstExchangeCompletedTimestamp.getUpdateCount() == 0) {
162                firstExchangeCompletedTimestamp.updateValue(now);
163            }
164    
165            lastExchangeCompletedTimestamp.updateValue(now);
166    
167            // update mean
168            long count = exchangesCompleted.getValue();
169            long mean = count > 0 ? totalProcessingTime.getValue() / count : 0;
170            meanProcessingTime.updateValue(mean);
171        }
172    
173        /**
174         * This method is called when an exchange has been processed and failed.
175         */
176        public synchronized void failedExchange() {
177            increment();
178            exchangesFailed.increment();
179    
180            long now = new Date().getTime();
181            if (firstExchangeFailureTimestamp.getUpdateCount() == 0) {
182                firstExchangeFailureTimestamp.updateValue(now);
183            }
184    
185            lastExchangeFailureTimestamp.updateValue(now);
186        }
187    
188    
189    }