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 }