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