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.text.SimpleDateFormat;
020 import java.util.Date;
021
022 import org.apache.camel.Exchange;
023 import org.apache.camel.api.management.ManagedResource;
024 import org.apache.camel.api.management.PerformanceCounter;
025 import org.apache.camel.api.management.mbean.ManagedPerformanceCounterMBean;
026 import org.apache.camel.spi.ManagementStrategy;
027 import org.apache.camel.util.ExchangeHelper;
028
029 @ManagedResource(description = "PerformanceCounter")
030 public abstract class ManagedPerformanceCounter extends ManagedCounter implements PerformanceCounter, ManagedPerformanceCounterMBean {
031
032 public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
033
034 private Statistic exchangesCompleted;
035 private Statistic exchangesFailed;
036 private Statistic failuresHandled;
037 private Statistic redeliveries;
038 private Statistic externalRedeliveries;
039 private Statistic minProcessingTime;
040 private Statistic maxProcessingTime;
041 private Statistic totalProcessingTime;
042 private Statistic lastProcessingTime;
043 private Statistic meanProcessingTime;
044 private Statistic firstExchangeCompletedTimestamp;
045 private String firstExchangeCompletedExchangeId;
046 private Statistic firstExchangeFailureTimestamp;
047 private String firstExchangeFailureExchangeId;
048 private Statistic lastExchangeCompletedTimestamp;
049 private String lastExchangeCompletedExchangeId;
050 private Statistic lastExchangeFailureTimestamp;
051 private String lastExchangeFailureExchangeId;
052 private boolean statisticsEnabled = true;
053
054 public void init(ManagementStrategy strategy) {
055 super.init(strategy);
056 this.exchangesCompleted = new Statistic("org.apache.camel.exchangesCompleted", this, Statistic.UpdateMode.COUNTER);
057 this.exchangesFailed = new Statistic("org.apache.camel.exchangesFailed", this, Statistic.UpdateMode.COUNTER);
058
059 this.failuresHandled = new Statistic("org.apache.camel.failuresHandled", this, Statistic.UpdateMode.COUNTER);
060 this.redeliveries = new Statistic("org.apache.camel.redeliveries", this, Statistic.UpdateMode.COUNTER);
061 this.externalRedeliveries = new Statistic("org.apache.camel.externalRedeliveries", this, Statistic.UpdateMode.COUNTER);
062
063 this.minProcessingTime = new Statistic("org.apache.camel.minimumProcessingTime", this, Statistic.UpdateMode.MINIMUM);
064 this.maxProcessingTime = new Statistic("org.apache.camel.maximumProcessingTime", this, Statistic.UpdateMode.MAXIMUM);
065 this.totalProcessingTime = new Statistic("org.apache.camel.totalProcessingTime", this, Statistic.UpdateMode.COUNTER);
066 this.lastProcessingTime = new Statistic("org.apache.camel.lastProcessingTime", this, Statistic.UpdateMode.VALUE);
067 this.meanProcessingTime = new Statistic("org.apache.camel.meanProcessingTime", this, Statistic.UpdateMode.VALUE);
068
069 this.firstExchangeCompletedTimestamp = new Statistic("org.apache.camel.firstExchangeCompletedTimestamp", this, Statistic.UpdateMode.VALUE);
070 this.firstExchangeFailureTimestamp = new Statistic("org.apache.camel.firstExchangeFailureTimestamp", this, Statistic.UpdateMode.VALUE);
071 this.lastExchangeCompletedTimestamp = new Statistic("org.apache.camel.lastExchangeCompletedTimestamp", this, Statistic.UpdateMode.VALUE);
072 this.lastExchangeFailureTimestamp = new Statistic("org.apache.camel.lastExchangeFailureTimestamp", this, Statistic.UpdateMode.VALUE);
073 }
074
075 @Override
076 public synchronized void reset() {
077 super.reset();
078 exchangesCompleted.reset();
079 exchangesFailed.reset();
080 failuresHandled.reset();
081 redeliveries.reset();
082 externalRedeliveries.reset();
083 minProcessingTime.reset();
084 maxProcessingTime.reset();
085 totalProcessingTime.reset();
086 lastProcessingTime.reset();
087 meanProcessingTime.reset();
088 firstExchangeCompletedTimestamp.reset();
089 firstExchangeCompletedExchangeId = null;
090 firstExchangeFailureTimestamp.reset();
091 firstExchangeFailureExchangeId = null;
092 lastExchangeCompletedTimestamp.reset();
093 lastExchangeCompletedExchangeId = null;
094 lastExchangeFailureTimestamp.reset();
095 lastExchangeFailureExchangeId = null;
096 }
097
098 public long getExchangesCompleted() throws Exception {
099 return exchangesCompleted.getValue();
100 }
101
102 public long getExchangesFailed() throws Exception {
103 return exchangesFailed.getValue();
104 }
105
106 public long getFailuresHandled() throws Exception {
107 return failuresHandled.getValue();
108 }
109
110 public long getRedeliveries() throws Exception {
111 return redeliveries.getValue();
112 }
113
114 public long getExternalRedeliveries() throws Exception {
115 return externalRedeliveries.getValue();
116 }
117
118 public long getMinProcessingTime() throws Exception {
119 return minProcessingTime.getValue();
120 }
121
122 public long getMeanProcessingTime() throws Exception {
123 return meanProcessingTime.getValue();
124 }
125
126 public long getMaxProcessingTime() throws Exception {
127 return maxProcessingTime.getValue();
128 }
129
130 public long getTotalProcessingTime() throws Exception {
131 return totalProcessingTime.getValue();
132 }
133
134 public long getLastProcessingTime() throws Exception {
135 return lastProcessingTime.getValue();
136 }
137
138 public Date getLastExchangeCompletedTimestamp() {
139 long value = lastExchangeCompletedTimestamp.getValue();
140 return value > 0 ? new Date(value) : null;
141 }
142
143 public String getLastExchangeCompletedExchangeId() {
144 return lastExchangeCompletedExchangeId;
145 }
146
147 public Date getFirstExchangeCompletedTimestamp() {
148 long value = firstExchangeCompletedTimestamp.getValue();
149 return value > 0 ? new Date(value) : null;
150 }
151
152 public String getFirstExchangeCompletedExchangeId() {
153 return firstExchangeCompletedExchangeId;
154 }
155
156 public Date getLastExchangeFailureTimestamp() {
157 long value = lastExchangeFailureTimestamp.getValue();
158 return value > 0 ? new Date(value) : null;
159 }
160
161 public String getLastExchangeFailureExchangeId() {
162 return lastExchangeFailureExchangeId;
163 }
164
165 public Date getFirstExchangeFailureTimestamp() {
166 long value = firstExchangeFailureTimestamp.getValue();
167 return value > 0 ? new Date(value) : null;
168 }
169
170 public String getFirstExchangeFailureExchangeId() {
171 return firstExchangeFailureExchangeId;
172 }
173
174 public boolean isStatisticsEnabled() {
175 return statisticsEnabled;
176 }
177
178 public void setStatisticsEnabled(boolean statisticsEnabled) {
179 this.statisticsEnabled = statisticsEnabled;
180 }
181
182 public synchronized void completedExchange(Exchange exchange, long time) {
183 increment();
184 exchangesCompleted.increment();
185
186 if (ExchangeHelper.isFailureHandled(exchange)) {
187 failuresHandled.increment();
188 }
189 Boolean externalRedelivered = exchange.isExternalRedelivered();
190 if (externalRedelivered != null && externalRedelivered) {
191 externalRedeliveries.increment();
192 }
193
194 minProcessingTime.updateValue(time);
195 maxProcessingTime.updateValue(time);
196 totalProcessingTime.updateValue(time);
197 lastProcessingTime.updateValue(time);
198
199 long now = new Date().getTime();
200 if (firstExchangeCompletedTimestamp.getUpdateCount() == 0) {
201 firstExchangeCompletedTimestamp.updateValue(now);
202 }
203
204 lastExchangeCompletedTimestamp.updateValue(now);
205 if (firstExchangeCompletedExchangeId == null) {
206 firstExchangeCompletedExchangeId = exchange.getExchangeId();
207 }
208 lastExchangeCompletedExchangeId = exchange.getExchangeId();
209
210 // update mean
211 long count = exchangesCompleted.getValue();
212 long mean = count > 0 ? totalProcessingTime.getValue() / count : 0;
213 meanProcessingTime.updateValue(mean);
214 }
215
216 public synchronized void failedExchange(Exchange exchange) {
217 increment();
218 exchangesFailed.increment();
219
220 if (ExchangeHelper.isRedelivered(exchange)) {
221 redeliveries.increment();
222 }
223 Boolean externalRedelivered = exchange.isExternalRedelivered();
224 if (externalRedelivered != null && externalRedelivered) {
225 externalRedeliveries.increment();
226 }
227
228 long now = new Date().getTime();
229 if (firstExchangeFailureTimestamp.getUpdateCount() == 0) {
230 firstExchangeFailureTimestamp.updateValue(now);
231 }
232
233 lastExchangeFailureTimestamp.updateValue(now);
234 if (firstExchangeFailureExchangeId == null) {
235 firstExchangeFailureExchangeId = exchange.getExchangeId();
236 }
237 lastExchangeFailureExchangeId = exchange.getExchangeId();
238 }
239
240 public String dumpStatsAsXml(boolean fullStats) {
241 StringBuilder sb = new StringBuilder();
242 sb.append("<stats ");
243 sb.append(String.format("exchangesCompleted=\"%s\"", exchangesCompleted.getValue()));
244 sb.append(String.format(" exchangesFailed=\"%s\"", exchangesFailed.getValue()));
245 sb.append(String.format(" failuresHandled=\"%s\"", failuresHandled.getValue()));
246 sb.append(String.format(" redeliveries=\"%s\"", redeliveries.getValue()));
247 sb.append(String.format(" externalRedeliveries=\"%s\"", externalRedeliveries.getValue()));
248 sb.append(String.format(" minProcessingTime=\"%s\"", minProcessingTime.getValue()));
249 sb.append(String.format(" maxProcessingTime=\"%s\"", maxProcessingTime.getValue()));
250 sb.append(String.format(" totalProcessingTime=\"%s\"", totalProcessingTime.getValue()));
251 sb.append(String.format(" lastProcessingTime=\"%s\"", lastProcessingTime.getValue()));
252 sb.append(String.format(" meanProcessingTime=\"%s\"", meanProcessingTime.getValue()));
253
254 if (fullStats) {
255 sb.append(String.format(" firstExchangeCompletedTimestamp=\"%s\"", dateAsString(firstExchangeCompletedTimestamp.getValue())));
256 sb.append(String.format(" firstExchangeCompletedExchangeId=\"%s\"", nullSafe(firstExchangeCompletedExchangeId)));
257 sb.append(String.format(" firstExchangeFailureTimestamp=\"%s\"", dateAsString(firstExchangeFailureTimestamp.getValue())));
258 sb.append(String.format(" firstExchangeFailureExchangeId=\"%s\"", nullSafe(firstExchangeFailureExchangeId)));
259 sb.append(String.format(" lastExchangeCompletedTimestamp=\"%s\"", dateAsString(lastExchangeCompletedTimestamp.getValue())));
260 sb.append(String.format(" lastExchangeCompletedExchangeId=\"%s\"", nullSafe(lastExchangeCompletedExchangeId)));
261 sb.append(String.format(" lastExchangeFailureTimestamp=\"%s\"", dateAsString(lastExchangeFailureTimestamp.getValue())));
262 sb.append(String.format(" lastExchangeFailureExchangeId=\"%s\"", nullSafe(lastExchangeFailureExchangeId)));
263 }
264 sb.append("/>");
265 return sb.toString();
266 }
267
268 private static String dateAsString(long value) {
269 if (value == 0) {
270 return "";
271 }
272 return new SimpleDateFormat(TIMESTAMP_FORMAT).format(value);
273 }
274
275 private static String nullSafe(String s) {
276 return s != null ? s : "";
277 }
278
279 }