blob: 81b262cdbb1a96a90b7ae9986356db7988b4a21f [file] [log] [blame]
/**
* 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.apache.aurora.common.stats;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.Nullable;
/**
* A class to represent the statistics associated with a client connection to an external service.
* Tracks request latency/rate, and error rate.
*
* @author William Farner
*/
public class RequestStats implements StatsProvider.RequestTimer {
private static final float DEFAULT_SAMPLE_PERCENT = 10;
private static final double[] DEFAULT_PERCENTILES = {10, 50, 90, 99, 99.9, 99.99};
private final SlidingStats requests;
private final Percentile<Long> percentile;
private final AtomicLong errors;
private final AtomicLong reconnects;
private final AtomicLong timeouts;
/**
* Creates a new request statistics object, using the default percentiles and sampling rate.
*
* @param name The unique name for this request type.
*/
public RequestStats(String name) {
this(name, new Percentile<Long>(name, DEFAULT_SAMPLE_PERCENT, DEFAULT_PERCENTILES));
}
/**
* Creates a new request statistics object using a custom percentile tracker.
*
* @param name The unique name for this request type.
* @param percentile The percentile tracker, or {@code null} to disable percentile tracking.
*/
public RequestStats(String name, @Nullable Percentile<Long> percentile) {
requests = new SlidingStats(name + "_requests", "micros");
this.percentile = percentile;
errors = Stats.exportLong(name + "_errors");
reconnects = Stats.exportLong(name + "_reconnects");
timeouts = Stats.exportLong(name + "_timeouts");
Rate<AtomicLong> requestsPerSec =
Rate.of(name + "_requests_per_sec", requests.getEventCounter()).build();
Stats.export(Ratio.of(name + "_error_rate",
Rate.of(name + "_errors_per_sec", errors).build(), requestsPerSec));
Rate<AtomicLong> timeoutsPerSec = Rate.of(name + "_timeouts_per_sec", timeouts).build();
Stats.export(timeoutsPerSec);
Stats.export(Ratio.of(name + "_timeout_rate", timeoutsPerSec, requestsPerSec));
}
public SlidingStats getSlidingStats() {
return requests;
}
public AtomicLong getErrorCounter() {
return errors;
}
public AtomicLong getReconnectCounter() {
return reconnects;
}
public AtomicLong getTimeoutCounter() {
return timeouts;
}
public Percentile<Long> getPercentile() {
return percentile;
}
/**
* Accumulates a request and its latency.
*
* @param latencyMicros The elapsed time required to complete the request.
*/
public void requestComplete(long latencyMicros) {
requests.accumulate(latencyMicros);
if (percentile != null) percentile.record(latencyMicros);
}
/**
* Accumulates the error counter and the request counter.
*/
public void incErrors() {
requestComplete(0);
errors.incrementAndGet();
}
/**
* Accumulates the error counter, the request counter and the request latency.
*
* @param latencyMicros The elapsed time before the error occurred.
*/
public void incErrors(long latencyMicros) {
requestComplete(latencyMicros);
errors.incrementAndGet();
}
/**
* Accumulates the reconnect counter.
*/
public void incReconnects() {
reconnects.incrementAndGet();
}
/**
* Accumulates the timtout counter.
*/
public void incTimeouts() {
timeouts.incrementAndGet();
}
public long getErrorCount() {
return errors.get();
}
public long getReconnectCount() {
return reconnects.get();
}
public long getTimeoutCount() {
return timeouts.get();
}
}