/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.management.mbean;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.camel.Exchange;
import org.apache.camel.api.management.ManagedResource;
import org.apache.camel.api.management.PerformanceCounter;
import org.apache.camel.api.management.mbean.ManagedPerformanceCounterMBean;
import org.apache.camel.spi.ManagementStrategy;
import org.apache.camel.util.ExchangeHelper;
@ManagedResource(description = "Managed PerformanceCounter")
public abstract class ManagedPerformanceCounter extends ManagedCounter implements PerformanceCounter, ManagedPerformanceCounterMBean {
public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
private Statistic exchangesCompleted;
private Statistic exchangesFailed;
private Statistic exchangesInflight;
private Statistic failuresHandled;
private Statistic redeliveries;
private Statistic externalRedeliveries;
private Statistic minProcessingTime;
private Statistic maxProcessingTime;
private Statistic totalProcessingTime;
private Statistic lastProcessingTime;
private Statistic deltaProcessingTime;
private Statistic meanProcessingTime;
private Statistic firstExchangeCompletedTimestamp;
private String firstExchangeCompletedExchangeId;
private Statistic firstExchangeFailureTimestamp;
private String firstExchangeFailureExchangeId;
private Statistic lastExchangeCompletedTimestamp;
private String lastExchangeCompletedExchangeId;
private Statistic lastExchangeFailureTimestamp;
private String lastExchangeFailureExchangeId;
private boolean statisticsEnabled = true;
public void init(ManagementStrategy strategy) {
super.init(strategy);
this.exchangesCompleted = new Statistic("org.apache.camel.exchangesCompleted", this, Statistic.UpdateMode.COUNTER);
this.exchangesFailed = new Statistic("org.apache.camel.exchangesFailed", this, Statistic.UpdateMode.COUNTER);
this.exchangesInflight = new Statistic("org.apache.camel.exchangesInflight", this, Statistic.UpdateMode.COUNTER);
this.failuresHandled = new Statistic("org.apache.camel.failuresHandled", this, Statistic.UpdateMode.COUNTER);
this.redeliveries = new Statistic("org.apache.camel.redeliveries", this, Statistic.UpdateMode.COUNTER);
this.externalRedeliveries = new Statistic("org.apache.camel.externalRedeliveries", this, Statistic.UpdateMode.COUNTER);
this.minProcessingTime = new Statistic("org.apache.camel.minimumProcessingTime", this, Statistic.UpdateMode.MINIMUM);
this.maxProcessingTime = new Statistic("org.apache.camel.maximumProcessingTime", this, Statistic.UpdateMode.MAXIMUM);
this.totalProcessingTime = new Statistic("org.apache.camel.totalProcessingTime", this, Statistic.UpdateMode.COUNTER);
this.lastProcessingTime = new Statistic("org.apache.camel.lastProcessingTime", this, Statistic.UpdateMode.VALUE);
this.deltaProcessingTime = new Statistic("org.apache.camel.deltaProcessingTime", this, Statistic.UpdateMode.DELTA);
this.meanProcessingTime = new Statistic("org.apache.camel.meanProcessingTime", this, Statistic.UpdateMode.VALUE);
this.firstExchangeCompletedTimestamp = new Statistic("org.apache.camel.firstExchangeCompletedTimestamp", this, Statistic.UpdateMode.VALUE);
this.firstExchangeFailureTimestamp = new Statistic("org.apache.camel.firstExchangeFailureTimestamp", this, Statistic.UpdateMode.VALUE);
this.lastExchangeCompletedTimestamp = new Statistic("org.apache.camel.lastExchangeCompletedTimestamp", this, Statistic.UpdateMode.VALUE);
this.lastExchangeFailureTimestamp = new Statistic("org.apache.camel.lastExchangeFailureTimestamp", this, Statistic.UpdateMode.VALUE);
}
@Override
public synchronized void reset() {
super.reset();
exchangesCompleted.reset();
exchangesFailed.reset();
exchangesInflight.reset();
failuresHandled.reset();
redeliveries.reset();
externalRedeliveries.reset();
minProcessingTime.reset();
maxProcessingTime.reset();
totalProcessingTime.reset();
lastProcessingTime.reset();
deltaProcessingTime.reset();
meanProcessingTime.reset();
firstExchangeCompletedTimestamp.reset();
firstExchangeCompletedExchangeId = null;
firstExchangeFailureTimestamp.reset();
firstExchangeFailureExchangeId = null;
lastExchangeCompletedTimestamp.reset();
lastExchangeCompletedExchangeId = null;
lastExchangeFailureTimestamp.reset();
lastExchangeFailureExchangeId = null;
}
public long getExchangesCompleted() throws Exception {
return exchangesCompleted.getValue();
}
public long getExchangesFailed() throws Exception {
return exchangesFailed.getValue();
}
public long getExchangesInflight() {
return exchangesInflight.getValue();
}
public long getFailuresHandled() throws Exception {
return failuresHandled.getValue();
}
public long getRedeliveries() throws Exception {
return redeliveries.getValue();
}
public long getExternalRedeliveries() throws Exception {
return externalRedeliveries.getValue();
}
public long getMinProcessingTime() throws Exception {
return minProcessingTime.getValue();
}
public long getMeanProcessingTime() throws Exception {
return meanProcessingTime.getValue();
}
public long getMaxProcessingTime() throws Exception {
return maxProcessingTime.getValue();
}
public long getTotalProcessingTime() throws Exception {
return totalProcessingTime.getValue();
}
public long getLastProcessingTime() throws Exception {
return lastProcessingTime.getValue();
}
public long getDeltaProcessingTime() throws Exception {
return deltaProcessingTime.getValue();
}
public Date getLastExchangeCompletedTimestamp() {
long value = lastExchangeCompletedTimestamp.getValue();
return value > 0 ? new Date(value) : null;
}
public String getLastExchangeCompletedExchangeId() {
return lastExchangeCompletedExchangeId;
}
public Date getFirstExchangeCompletedTimestamp() {
long value = firstExchangeCompletedTimestamp.getValue();
return value > 0 ? new Date(value) : null;
}
public String getFirstExchangeCompletedExchangeId() {
return firstExchangeCompletedExchangeId;
}
public Date getLastExchangeFailureTimestamp() {
long value = lastExchangeFailureTimestamp.getValue();
return value > 0 ? new Date(value) : null;
}
public String getLastExchangeFailureExchangeId() {
return lastExchangeFailureExchangeId;
}
public Date getFirstExchangeFailureTimestamp() {
long value = firstExchangeFailureTimestamp.getValue();
return value > 0 ? new Date(value) : null;
}
public String getFirstExchangeFailureExchangeId() {
return firstExchangeFailureExchangeId;
}
public boolean isStatisticsEnabled() {
return statisticsEnabled;
}
public void setStatisticsEnabled(boolean statisticsEnabled) {
this.statisticsEnabled = statisticsEnabled;
}
public synchronized void processExchange(Exchange exchange) {
exchangesInflight.increment();
}
public synchronized void completedExchange(Exchange exchange, long time) {
increment();
exchangesCompleted.increment();
exchangesInflight.decrement();
if (ExchangeHelper.isFailureHandled(exchange)) {
failuresHandled.increment();
}
Boolean externalRedelivered = exchange.isExternalRedelivered();
if (externalRedelivered != null && externalRedelivered) {
externalRedeliveries.increment();
}
minProcessingTime.updateValue(time);
maxProcessingTime.updateValue(time);
totalProcessingTime.updateValue(time);
lastProcessingTime.updateValue(time);
deltaProcessingTime.updateValue(time);
long now = new Date().getTime();
if (firstExchangeCompletedTimestamp.getUpdateCount() == 0) {
firstExchangeCompletedTimestamp.updateValue(now);
}
lastExchangeCompletedTimestamp.updateValue(now);
if (firstExchangeCompletedExchangeId == null) {
firstExchangeCompletedExchangeId = exchange.getExchangeId();
}
lastExchangeCompletedExchangeId = exchange.getExchangeId();
// update mean
long count = exchangesCompleted.getValue();
long mean = count > 0 ? totalProcessingTime.getValue() / count : 0;
meanProcessingTime.updateValue(mean);
}
public synchronized void failedExchange(Exchange exchange) {
increment();
exchangesFailed.increment();
exchangesInflight.decrement();
if (ExchangeHelper.isRedelivered(exchange)) {
redeliveries.increment();
}
Boolean externalRedelivered = exchange.isExternalRedelivered();
if (externalRedelivered != null && externalRedelivered) {
externalRedeliveries.increment();
}
long now = new Date().getTime();
if (firstExchangeFailureTimestamp.getUpdateCount() == 0) {
firstExchangeFailureTimestamp.updateValue(now);
}
lastExchangeFailureTimestamp.updateValue(now);
if (firstExchangeFailureExchangeId == null) {
firstExchangeFailureExchangeId = exchange.getExchangeId();
}
lastExchangeFailureExchangeId = exchange.getExchangeId();
}
public String dumpStatsAsXml(boolean fullStats) {
StringBuilder sb = new StringBuilder();
sb.append("<stats ");
sb.append(String.format("exchangesCompleted=\"%s\"", exchangesCompleted.getValue()));
sb.append(String.format(" exchangesFailed=\"%s\"", exchangesFailed.getValue()));
sb.append(String.format(" failuresHandled=\"%s\"", failuresHandled.getValue()));
sb.append(String.format(" redeliveries=\"%s\"", redeliveries.getValue()));
sb.append(String.format(" externalRedeliveries=\"%s\"", externalRedeliveries.getValue()));
sb.append(String.format(" minProcessingTime=\"%s\"", minProcessingTime.getValue()));
sb.append(String.format(" maxProcessingTime=\"%s\"", maxProcessingTime.getValue()));
sb.append(String.format(" totalProcessingTime=\"%s\"", totalProcessingTime.getValue()));
sb.append(String.format(" lastProcessingTime=\"%s\"", lastProcessingTime.getValue()));
sb.append(String.format(" deltaProcessingTime=\"%s\"", deltaProcessingTime.getValue()));
sb.append(String.format(" meanProcessingTime=\"%s\"", meanProcessingTime.getValue()));
if (fullStats) {
sb.append(String.format(" startTimestamp=\"%s\"", dateAsString(startTimestamp.getValue())));
sb.append(String.format(" resetTimestamp=\"%s\"", dateAsString(resetTimestamp.getValue())));
sb.append(String.format(" firstExchangeCompletedTimestamp=\"%s\"", dateAsString(firstExchangeCompletedTimestamp.getValue())));
sb.append(String.format(" firstExchangeCompletedExchangeId=\"%s\"", nullSafe(firstExchangeCompletedExchangeId)));
sb.append(String.format(" firstExchangeFailureTimestamp=\"%s\"", dateAsString(firstExchangeFailureTimestamp.getValue())));
sb.append(String.format(" firstExchangeFailureExchangeId=\"%s\"", nullSafe(firstExchangeFailureExchangeId)));
sb.append(String.format(" lastExchangeCompletedTimestamp=\"%s\"", dateAsString(lastExchangeCompletedTimestamp.getValue())));
sb.append(String.format(" lastExchangeCompletedExchangeId=\"%s\"", nullSafe(lastExchangeCompletedExchangeId)));
sb.append(String.format(" lastExchangeFailureTimestamp=\"%s\"", dateAsString(lastExchangeFailureTimestamp.getValue())));
sb.append(String.format(" lastExchangeFailureExchangeId=\"%s\"", nullSafe(lastExchangeFailureExchangeId)));
}
sb.append("/>");
return sb.toString();
}
private static String dateAsString(long value) {
if (value == 0) {
return "";
}
return new SimpleDateFormat(TIMESTAMP_FORMAT).format(value);
}
private static String nullSafe(String s) {
return s != null ? s : "";
}
}