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 Statistic("org.apache.camel.exchangesCompleted", this, Statistic.UpdateMode.COUNTER); 059 this.exchangesFailed = new Statistic("org.apache.camel.exchangesFailed", this, Statistic.UpdateMode.COUNTER); 060 this.exchangesInflight = new Statistic("org.apache.camel.exchangesInflight", this, Statistic.UpdateMode.COUNTER); 061 062 this.failuresHandled = new Statistic("org.apache.camel.failuresHandled", this, Statistic.UpdateMode.COUNTER); 063 this.redeliveries = new Statistic("org.apache.camel.redeliveries", this, Statistic.UpdateMode.COUNTER); 064 this.externalRedeliveries = new Statistic("org.apache.camel.externalRedeliveries", this, Statistic.UpdateMode.COUNTER); 065 066 this.minProcessingTime = new Statistic("org.apache.camel.minimumProcessingTime", this, Statistic.UpdateMode.MINIMUM); 067 this.maxProcessingTime = new Statistic("org.apache.camel.maximumProcessingTime", this, Statistic.UpdateMode.MAXIMUM); 068 this.totalProcessingTime = new Statistic("org.apache.camel.totalProcessingTime", this, Statistic.UpdateMode.COUNTER); 069 this.lastProcessingTime = new Statistic("org.apache.camel.lastProcessingTime", this, Statistic.UpdateMode.VALUE); 070 this.deltaProcessingTime = new Statistic("org.apache.camel.deltaProcessingTime", this, Statistic.UpdateMode.DELTA); 071 this.meanProcessingTime = new Statistic("org.apache.camel.meanProcessingTime", this, Statistic.UpdateMode.VALUE); 072 073 this.firstExchangeCompletedTimestamp = new Statistic("org.apache.camel.firstExchangeCompletedTimestamp", this, Statistic.UpdateMode.VALUE); 074 this.firstExchangeFailureTimestamp = new Statistic("org.apache.camel.firstExchangeFailureTimestamp", this, Statistic.UpdateMode.VALUE); 075 this.lastExchangeCompletedTimestamp = new Statistic("org.apache.camel.lastExchangeCompletedTimestamp", this, Statistic.UpdateMode.VALUE); 076 this.lastExchangeFailureTimestamp = new Statistic("org.apache.camel.lastExchangeFailureTimestamp", this, Statistic.UpdateMode.VALUE); 077 } 078 079 @Override 080 public synchronized 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 synchronized void processExchange(Exchange exchange) { 197 exchangesInflight.increment(); 198 } 199 200 public synchronized 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 = new Date().getTime(); 220 if (firstExchangeCompletedTimestamp.getUpdateCount() == 0) { 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 count = exchangesCompleted.getValue(); 232 long mean = count > 0 ? totalProcessingTime.getValue() / count : 0; 233 meanProcessingTime.updateValue(mean); 234 } 235 236 public synchronized void failedExchange(Exchange exchange) { 237 increment(); 238 exchangesFailed.increment(); 239 exchangesInflight.decrement(); 240 241 if (ExchangeHelper.isRedelivered(exchange)) { 242 redeliveries.increment(); 243 } 244 Boolean externalRedelivered = exchange.isExternalRedelivered(); 245 if (externalRedelivered != null && externalRedelivered) { 246 externalRedeliveries.increment(); 247 } 248 249 long now = new Date().getTime(); 250 if (firstExchangeFailureTimestamp.getUpdateCount() == 0) { 251 firstExchangeFailureTimestamp.updateValue(now); 252 } 253 254 lastExchangeFailureTimestamp.updateValue(now); 255 if (firstExchangeFailureExchangeId == null) { 256 firstExchangeFailureExchangeId = exchange.getExchangeId(); 257 } 258 lastExchangeFailureExchangeId = exchange.getExchangeId(); 259 } 260 261 public String dumpStatsAsXml(boolean fullStats) { 262 StringBuilder sb = new StringBuilder(); 263 sb.append("<stats "); 264 sb.append(String.format("exchangesCompleted=\"%s\"", exchangesCompleted.getValue())); 265 sb.append(String.format(" exchangesFailed=\"%s\"", exchangesFailed.getValue())); 266 sb.append(String.format(" failuresHandled=\"%s\"", failuresHandled.getValue())); 267 sb.append(String.format(" redeliveries=\"%s\"", redeliveries.getValue())); 268 sb.append(String.format(" externalRedeliveries=\"%s\"", externalRedeliveries.getValue())); 269 sb.append(String.format(" minProcessingTime=\"%s\"", minProcessingTime.getValue())); 270 sb.append(String.format(" maxProcessingTime=\"%s\"", maxProcessingTime.getValue())); 271 sb.append(String.format(" totalProcessingTime=\"%s\"", totalProcessingTime.getValue())); 272 sb.append(String.format(" lastProcessingTime=\"%s\"", lastProcessingTime.getValue())); 273 sb.append(String.format(" deltaProcessingTime=\"%s\"", deltaProcessingTime.getValue())); 274 sb.append(String.format(" meanProcessingTime=\"%s\"", meanProcessingTime.getValue())); 275 276 if (fullStats) { 277 sb.append(String.format(" startTimestamp=\"%s\"", dateAsString(startTimestamp.getValue()))); 278 sb.append(String.format(" resetTimestamp=\"%s\"", dateAsString(resetTimestamp.getValue()))); 279 sb.append(String.format(" firstExchangeCompletedTimestamp=\"%s\"", dateAsString(firstExchangeCompletedTimestamp.getValue()))); 280 sb.append(String.format(" firstExchangeCompletedExchangeId=\"%s\"", nullSafe(firstExchangeCompletedExchangeId))); 281 sb.append(String.format(" firstExchangeFailureTimestamp=\"%s\"", dateAsString(firstExchangeFailureTimestamp.getValue()))); 282 sb.append(String.format(" firstExchangeFailureExchangeId=\"%s\"", nullSafe(firstExchangeFailureExchangeId))); 283 sb.append(String.format(" lastExchangeCompletedTimestamp=\"%s\"", dateAsString(lastExchangeCompletedTimestamp.getValue()))); 284 sb.append(String.format(" lastExchangeCompletedExchangeId=\"%s\"", nullSafe(lastExchangeCompletedExchangeId))); 285 sb.append(String.format(" lastExchangeFailureTimestamp=\"%s\"", dateAsString(lastExchangeFailureTimestamp.getValue()))); 286 sb.append(String.format(" lastExchangeFailureExchangeId=\"%s\"", nullSafe(lastExchangeFailureExchangeId))); 287 } 288 sb.append("/>"); 289 return sb.toString(); 290 } 291 292 private static String dateAsString(long value) { 293 if (value == 0) { 294 return ""; 295 } 296 return new SimpleDateFormat(TIMESTAMP_FORMAT).format(value); 297 } 298 299 private static String nullSafe(String s) { 300 return s != null ? s : ""; 301 } 302 303}