| /** |
| * 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(); |
| } |
| } |