/* * Copyright 2002-2015 the original author or authors. * * Licensed 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.springframework.integration.support.management; import java.util.concurrent.atomic.AtomicLong; /** * Default implementation; use the full constructor to customize the moving averages. * * @author Dave Syer * @author Gary Russell * @since 2.0 */ public class DefaultMessageHandlerMetrics extends AbstractMessageHandlerMetrics { private static final int DEFAULT_MOVING_AVERAGE_WINDOW = 10; protected final AtomicLong activeCount = new AtomicLong(); protected final AtomicLong handleCount = new AtomicLong(); protected final AtomicLong errorCount = new AtomicLong(); protected final ExponentialMovingAverage duration; public DefaultMessageHandlerMetrics() { this(null); } /** * Construct an instance with the default moving average window (10). * @param name the name. */ public DefaultMessageHandlerMetrics(String name) { this(name, new ExponentialMovingAverage(DEFAULT_MOVING_AVERAGE_WINDOW, 1000000.)); } /** * Construct an instance with the supplied {@link ExponentialMovingAverage} calculating * the duration of processing by the message handler (and any downstream synchronous * endpoints). * @param name the name. * @param duration an {@link ExponentialMovingAverage} for calculating the duration. * @since 4.2 */ public DefaultMessageHandlerMetrics(String name, ExponentialMovingAverage duration) { super(name); this.duration = duration; } @Override public MetricsContext beforeHandle() { long start = 0; if (isFullStatsEnabled()) { start = System.nanoTime(); } this.handleCount.incrementAndGet(); this.activeCount.incrementAndGet(); return new DefaultHandlerMetricsContext(start); } @Override public void afterHandle(MetricsContext context, boolean success) { this.activeCount.decrementAndGet(); if (isFullStatsEnabled() && success) { this.duration.append(System.nanoTime() - ((DefaultHandlerMetricsContext) context).start); } else if (!success) { this.errorCount.incrementAndGet(); } } @Override public synchronized void reset() { this.duration.reset(); this.errorCount.set(0); this.handleCount.set(0); } @Override public long getHandleCountLong() { if (logger.isTraceEnabled()) { logger.trace("Getting Handle Count:" + this); } return this.handleCount.get(); } @Override public int getHandleCount() { return (int) getHandleCountLong(); } @Override public int getErrorCount() { return (int) this.errorCount.get(); } @Override public long getErrorCountLong() { return this.errorCount.get(); } @Override public double getMeanDuration() { return this.duration.getMean(); } @Override public double getMinDuration() { return this.duration.getMin(); } @Override public double getMaxDuration() { return this.duration.getMax(); } @Override public double getStandardDeviationDuration() { return this.duration.getStandardDeviation(); } @Override public int getActiveCount() { return (int) this.activeCount.get(); } @Override public long getActiveCountLong() { return this.activeCount.get(); } @Override public Statistics getDuration() { return this.duration.getStatistics(); } protected static class DefaultHandlerMetricsContext implements MetricsContext { protected final long start; protected DefaultHandlerMetricsContext(long start) { this.start = start; } } }