package com.twitter.common.stats;
import java.util.concurrent.atomic.AtomicLong;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.twitter.common.base.MorePreconditions;
import com.twitter.common.quantity.Amount;
import com.twitter.common.quantity.Time;
import com.twitter.common.util.Clock;
/**
* A stat that exports the amount of time since it was last reset.
*
* @author William Farner
*/
public class Elapsed {
private final Clock clock;
private final AtomicLong lastEventNs = new AtomicLong();
/**
* Calls {@link #Elapsed(String, Time)} using a default granularity of nanoseconds.
*
* @param name Name of the stat to export.
*/
public Elapsed(String name) {
this(name, Time.NANOSECONDS);
}
/**
* Creates and exports a new stat that maintains the difference between the system clock time
* and the time since it was last reset. Upon export, the counter will act as though it were just
* reset.
*
* @param name Name of the stat to export.
* @param granularity Time unit granularity to export.
*/
public Elapsed(String name, Time granularity) {
this(name, granularity, Clock.SYSTEM_CLOCK);
}
@VisibleForTesting
Elapsed(String name, final Time granularity, final Clock clock) {
MorePreconditions.checkNotBlank(name);
Preconditions.checkNotNull(granularity);
this.clock = Preconditions.checkNotNull(clock);
reset();
Stats.export(new StatImpl<Long>(name) {
@Override public Long read() {
return Amount.of(clock.nowNanos() - lastEventNs.get(), Time.NANOSECONDS).as(granularity);
}
});
}
public void reset() {
lastEventNs.set(clock.nowNanos());
}
}