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