package com.twitter.common.metrics;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.twitter.common.util.Clock;
/**
* A sampler that associates a {@link MetricProvider} with multiple {@link MetricListener}s.
*/
class MetricSampler implements Runnable {
private final MetricProvider metricProvier;
private final List<MetricListener> listeners;
private final Clock clock;
private final Events events;
/**
* Creates a new metric sampler.
*
* @param metricProvider Source of metric samples.
* @param listeners Sample sinks.
* @param registry Registry to export sampling-related metrics to.
* @param clock Clock for timing metric sample duration.
*/
@VisibleForTesting
MetricSampler(MetricProvider metricProvider, Iterable<MetricListener> listeners,
MetricRegistry registry, Clock clock) {
this.metricProvier = Preconditions.checkNotNull(metricProvider);
this.listeners = new CopyOnWriteArrayList<MetricListener>(ImmutableList.copyOf(listeners));
this.clock = Preconditions.checkNotNull(clock);
Preconditions.checkNotNull(registry);
this.events = new Events("metric_samples", "metric_sample_delay", registry);
}
public void addListener(MetricListener listener) {
listeners.add(listener);
}
@Override
public void run() {
long startNanos = clock.nowNanos();
Map<String, Number> metrics = metricProvier.sample();
events.accumulate(clock.nowNanos() - startNanos);
for (MetricListener listener : listeners) {
listener.updateStats(metrics);
}
}
}