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.camel.management.mbean; 018 019import java.text.SimpleDateFormat; 020import java.util.Date; 021 022import org.apache.camel.Exchange; 023import org.apache.camel.api.management.ManagedResource; 024import org.apache.camel.api.management.mbean.ManagedPerformanceCounterMBean; 025import org.apache.camel.management.PerformanceCounter; 026import org.apache.camel.spi.ManagementStrategy; 027import org.apache.camel.support.ExchangeHelper; 028 029@ManagedResource(description = "Managed PerformanceCounter") 030public 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 exchangesInflight; 037 private Statistic failuresHandled; 038 private Statistic redeliveries; 039 private Statistic externalRedeliveries; 040 private Statistic minProcessingTime; 041 private Statistic maxProcessingTime; 042 private Statistic totalProcessingTime; 043 private Statistic lastProcessingTime; 044 private Statistic deltaProcessingTime; 045 private Statistic meanProcessingTime; 046 private Statistic firstExchangeCompletedTimestamp; 047 private String firstExchangeCompletedExchangeId; 048 private Statistic firstExchangeFailureTimestamp; 049 private String firstExchangeFailureExchangeId; 050 private Statistic lastExchangeCompletedTimestamp; 051 private String lastExchangeCompletedExchangeId; 052 private Statistic lastExchangeFailureTimestamp; 053 private String lastExchangeFailureExchangeId; 054 private boolean statisticsEnabled = true; 055 056 @Override 057 public void init(ManagementStrategy strategy) { 058 super.init(strategy); 059 this.exchangesCompleted = new StatisticCounter(); 060 this.exchangesFailed = new StatisticCounter(); 061 this.exchangesInflight = new StatisticCounter(); 062 063 this.failuresHandled = new StatisticCounter(); 064 this.redeliveries = new StatisticCounter(); 065 this.externalRedeliveries = new StatisticCounter(); 066 067 this.minProcessingTime = new StatisticMinimum(); 068 this.maxProcessingTime = new StatisticMaximum(); 069 this.totalProcessingTime = new StatisticCounter(); 070 this.lastProcessingTime = new StatisticValue(); 071 this.deltaProcessingTime = new StatisticDelta(); 072 this.meanProcessingTime = new StatisticValue(); 073 074 this.firstExchangeCompletedTimestamp = new StatisticValue(); 075 this.firstExchangeFailureTimestamp = new StatisticValue(); 076 this.lastExchangeCompletedTimestamp = new StatisticValue(); 077 this.lastExchangeFailureTimestamp = new StatisticValue(); 078 } 079 080 @Override 081 public void reset() { 082 super.reset(); 083 exchangesCompleted.reset(); 084 exchangesFailed.reset(); 085 exchangesInflight.reset(); 086 failuresHandled.reset(); 087 redeliveries.reset(); 088 externalRedeliveries.reset(); 089 minProcessingTime.reset(); 090 maxProcessingTime.reset(); 091 totalProcessingTime.reset(); 092 lastProcessingTime.reset(); 093 deltaProcessingTime.reset(); 094 meanProcessingTime.reset(); 095 firstExchangeCompletedTimestamp.reset(); 096 firstExchangeCompletedExchangeId = null; 097 firstExchangeFailureTimestamp.reset(); 098 firstExchangeFailureExchangeId = null; 099 lastExchangeCompletedTimestamp.reset(); 100 lastExchangeCompletedExchangeId = null; 101 lastExchangeFailureTimestamp.reset(); 102 lastExchangeFailureExchangeId = null; 103 } 104 105 @Override 106 public long getExchangesCompleted() throws Exception { 107 return exchangesCompleted.getValue(); 108 } 109 110 @Override 111 public long getExchangesFailed() throws Exception { 112 return exchangesFailed.getValue(); 113 } 114 115 @Override 116 public long getExchangesInflight() { 117 return exchangesInflight.getValue(); 118 } 119 120 @Override 121 public long getFailuresHandled() throws Exception { 122 return failuresHandled.getValue(); 123 } 124 125 @Override 126 public long getRedeliveries() throws Exception { 127 return redeliveries.getValue(); 128 } 129 130 @Override 131 public long getExternalRedeliveries() throws Exception { 132 return externalRedeliveries.getValue(); 133 } 134 135 @Override 136 public long getMinProcessingTime() throws Exception { 137 return minProcessingTime.getValue(); 138 } 139 140 @Override 141 public long getMeanProcessingTime() throws Exception { 142 return meanProcessingTime.getValue(); 143 } 144 145 @Override 146 public long getMaxProcessingTime() throws Exception { 147 return maxProcessingTime.getValue(); 148 } 149 150 @Override 151 public long getTotalProcessingTime() throws Exception { 152 return totalProcessingTime.getValue(); 153 } 154 155 @Override 156 public long getLastProcessingTime() throws Exception { 157 return lastProcessingTime.getValue(); 158 } 159 160 @Override 161 public long getDeltaProcessingTime() throws Exception { 162 return deltaProcessingTime.getValue(); 163 } 164 165 @Override 166 public Date getLastExchangeCompletedTimestamp() { 167 long value = lastExchangeCompletedTimestamp.getValue(); 168 return value > 0 ? new Date(value) : null; 169 } 170 171 @Override 172 public String getLastExchangeCompletedExchangeId() { 173 return lastExchangeCompletedExchangeId; 174 } 175 176 @Override 177 public Date getFirstExchangeCompletedTimestamp() { 178 long value = firstExchangeCompletedTimestamp.getValue(); 179 return value > 0 ? new Date(value) : null; 180 } 181 182 @Override 183 public String getFirstExchangeCompletedExchangeId() { 184 return firstExchangeCompletedExchangeId; 185 } 186 187 @Override 188 public Date getLastExchangeFailureTimestamp() { 189 long value = lastExchangeFailureTimestamp.getValue(); 190 return value > 0 ? new Date(value) : null; 191 } 192 193 @Override 194 public String getLastExchangeFailureExchangeId() { 195 return lastExchangeFailureExchangeId; 196 } 197 198 @Override 199 public Date getFirstExchangeFailureTimestamp() { 200 long value = firstExchangeFailureTimestamp.getValue(); 201 return value > 0 ? new Date(value) : null; 202 } 203 204 @Override 205 public String getFirstExchangeFailureExchangeId() { 206 return firstExchangeFailureExchangeId; 207 } 208 209 @Override 210 public boolean isStatisticsEnabled() { 211 return statisticsEnabled; 212 } 213 214 @Override 215 public void setStatisticsEnabled(boolean statisticsEnabled) { 216 this.statisticsEnabled = statisticsEnabled; 217 } 218 219 @Override 220 public void processExchange(Exchange exchange) { 221 exchangesInflight.increment(); 222 } 223 224 @Override 225 public void completedExchange(Exchange exchange, long time) { 226 increment(); 227 exchangesCompleted.increment(); 228 exchangesInflight.decrement(); 229 230 if (ExchangeHelper.isFailureHandled(exchange)) { 231 failuresHandled.increment(); 232 } 233 if (exchange.isExternalRedelivered()) { 234 externalRedeliveries.increment(); 235 } 236 237 minProcessingTime.updateValue(time); 238 maxProcessingTime.updateValue(time); 239 totalProcessingTime.updateValue(time); 240 lastProcessingTime.updateValue(time); 241 deltaProcessingTime.updateValue(time); 242 243 long now = System.currentTimeMillis(); 244 if (!firstExchangeCompletedTimestamp.isUpdated()) { 245 firstExchangeCompletedTimestamp.updateValue(now); 246 } 247 248 lastExchangeCompletedTimestamp.updateValue(now); 249 if (firstExchangeCompletedExchangeId == null) { 250 firstExchangeCompletedExchangeId = exchange.getExchangeId(); 251 } 252 lastExchangeCompletedExchangeId = exchange.getExchangeId(); 253 254 // update mean 255 long mean = 0; 256 long completed = exchangesCompleted.getValue(); 257 if (completed > 0) { 258 mean = totalProcessingTime.getValue() / completed; 259 } 260 meanProcessingTime.updateValue(mean); 261 } 262 263 @Override 264 public void failedExchange(Exchange exchange) { 265 increment(); 266 exchangesFailed.increment(); 267 exchangesInflight.decrement(); 268 269 if (ExchangeHelper.isRedelivered(exchange)) { 270 redeliveries.increment(); 271 } 272 if (exchange.isExternalRedelivered()) { 273 externalRedeliveries.increment(); 274 } 275 276 long now = System.currentTimeMillis(); 277 if (!firstExchangeFailureTimestamp.isUpdated()) { 278 firstExchangeFailureTimestamp.updateValue(now); 279 } 280 281 lastExchangeFailureTimestamp.updateValue(now); 282 if (firstExchangeFailureExchangeId == null) { 283 firstExchangeFailureExchangeId = exchange.getExchangeId(); 284 } 285 lastExchangeFailureExchangeId = exchange.getExchangeId(); 286 } 287 288 @Override 289 public String dumpStatsAsXml(boolean fullStats) { 290 StringBuilder sb = new StringBuilder(); 291 sb.append("<stats "); 292 sb.append(String.format("exchangesCompleted=\"%s\"", exchangesCompleted.getValue())); 293 sb.append(String.format(" exchangesFailed=\"%s\"", exchangesFailed.getValue())); 294 sb.append(String.format(" failuresHandled=\"%s\"", failuresHandled.getValue())); 295 sb.append(String.format(" redeliveries=\"%s\"", redeliveries.getValue())); 296 sb.append(String.format(" externalRedeliveries=\"%s\"", externalRedeliveries.getValue())); 297 sb.append(String.format(" minProcessingTime=\"%s\"", minProcessingTime.getValue())); 298 sb.append(String.format(" maxProcessingTime=\"%s\"", maxProcessingTime.getValue())); 299 sb.append(String.format(" totalProcessingTime=\"%s\"", totalProcessingTime.getValue())); 300 sb.append(String.format(" lastProcessingTime=\"%s\"", lastProcessingTime.getValue())); 301 sb.append(String.format(" deltaProcessingTime=\"%s\"", deltaProcessingTime.getValue())); 302 sb.append(String.format(" meanProcessingTime=\"%s\"", meanProcessingTime.getValue())); 303 304 if (fullStats) { 305 sb.append(String.format(" startTimestamp=\"%s\"", dateAsString(startTimestamp.getTime()))); 306 sb.append(String.format(" resetTimestamp=\"%s\"", dateAsString(resetTimestamp.getTime()))); 307 sb.append(String.format(" firstExchangeCompletedTimestamp=\"%s\"", dateAsString(firstExchangeCompletedTimestamp.getValue()))); 308 sb.append(String.format(" firstExchangeCompletedExchangeId=\"%s\"", nullSafe(firstExchangeCompletedExchangeId))); 309 sb.append(String.format(" firstExchangeFailureTimestamp=\"%s\"", dateAsString(firstExchangeFailureTimestamp.getValue()))); 310 sb.append(String.format(" firstExchangeFailureExchangeId=\"%s\"", nullSafe(firstExchangeFailureExchangeId))); 311 sb.append(String.format(" lastExchangeCompletedTimestamp=\"%s\"", dateAsString(lastExchangeCompletedTimestamp.getValue()))); 312 sb.append(String.format(" lastExchangeCompletedExchangeId=\"%s\"", nullSafe(lastExchangeCompletedExchangeId))); 313 sb.append(String.format(" lastExchangeFailureTimestamp=\"%s\"", dateAsString(lastExchangeFailureTimestamp.getValue()))); 314 sb.append(String.format(" lastExchangeFailureExchangeId=\"%s\"", nullSafe(lastExchangeFailureExchangeId))); 315 } 316 sb.append("/>"); 317 return sb.toString(); 318 } 319 320 private static String dateAsString(long value) { 321 if (value <= 0) { 322 return ""; 323 } 324 return new SimpleDateFormat(TIMESTAMP_FORMAT).format(value); 325 } 326 327 private static String nullSafe(String s) { 328 return s != null ? s : ""; 329 } 330 331}