// =================================================================================================
// Copyright 2011 Twitter, Inc.
// -------------------------------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this work except in compliance with the License.
// You may obtain a copy of the License in the LICENSE file, or 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 com.twitter.common.stats;
import com.twitter.common.base.MorePreconditions;
import java.util.concurrent.atomic.AtomicLong;
/**
* Tracks event statistics over a sliding window of time. An event is something that has a
* frequency and associated total.
*
* @author William Farner
*/
public class SlidingStats {
private static final int DEFAULT_WINDOW_SIZE = 1;
private final AtomicLong total;
private final AtomicLong events;
private final Stat<Double> perEventLatency;
/**
* Creates a new sliding statistic with the given name
*
* @param name Name for this stat collection.
* @param totalUnitDisplay String to display for the total counter unit.
*/
public SlidingStats(String name, String totalUnitDisplay) {
this(name, totalUnitDisplay, DEFAULT_WINDOW_SIZE);
}
/**
* Creates a new sliding statistic with the given name
*
* @param name Name for this stat collection.
* @param totalUnitDisplay String to display for the total counter unit.
* @param windowSize The window size for the per second Rate and Ratio stats.
*/
public SlidingStats(String name, String totalUnitDisplay, int windowSize) {
MorePreconditions.checkNotBlank(name);
String totalDisplay = name + "_" + totalUnitDisplay + "_total";
String eventDisplay = name + "_events";
total = Stats.exportLong(totalDisplay);
events = Stats.exportLong(eventDisplay);
perEventLatency = Stats.export(Ratio.of(name + "_" + totalUnitDisplay + "_per_event",
Rate.of(totalDisplay + "_per_sec", total).withWindowSize(windowSize).build(),
Rate.of(eventDisplay + "_per_sec", events).withWindowSize(windowSize).build()));
}
public AtomicLong getTotalCounter() {
return total;
}
public AtomicLong getEventCounter() {
return events;
}
public Stat<Double> getPerEventLatency() {
return perEventLatency;
}
/**
* Accumulates counter by an offset. This is is useful for tracking things like
* latency of operations.
*
* TODO(William Farner): Implement a wrapper to SlidingStats that expects to accumulate time, and can
* convert between time units.
*
* @param value The value to accumulate.
*/
public synchronized void accumulate(long value) {
total.addAndGet(value);
events.incrementAndGet();
}
@Override
public String toString() {
return total + " " + events;
}
}