Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying a default reservoir for a registry. #680

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
* Proceedings of the 2009 IEEE International Conference on Data Engineering (2009)</a>
*/
public class ExponentiallyDecayingReservoir implements Reservoir {
private static final int DEFAULT_SIZE = 1028;
private static final double DEFAULT_ALPHA = 0.015;
static final int DEFAULT_SIZE = 1028;
static final double DEFAULT_ALPHA = 0.015;
private static final long RESCALE_THRESHOLD = TimeUnit.HOURS.toNanos(1);

private final ConcurrentSkipListMap<Double, WeightedSample> values;
Expand Down
103 changes: 55 additions & 48 deletions metrics-core/src/main/java/com/codahale/metrics/MetricRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,22 @@ private static void append(StringBuilder builder, String part) {

private final ConcurrentMap<String, Metric> metrics;
private final List<MetricRegistryListener> listeners;
private final ReservoirBuilder reservoirBuilder;

/**
* Creates a new {@link MetricRegistry}.
*/
public MetricRegistry() {
public MetricRegistry(ReservoirBuilder reservoirBuilder) {
this.reservoirBuilder = reservoirBuilder;
this.metrics = buildMap();
this.listeners = new CopyOnWriteArrayList<MetricRegistryListener>();
}

public MetricRegistry() {
this(new ReservoirBuilder.ExponentiallyDecayingReservoirBuilder(ExponentiallyDecayingReservoir.DEFAULT_SIZE,
ExponentiallyDecayingReservoir.DEFAULT_ALPHA));
}

/**
* Creates a new {@link ConcurrentMap} implementation for use inside the registry. Override this
* to create a {@link MetricRegistry} with space- or time-bounded metric lifecycles, for
Expand Down Expand Up @@ -111,7 +118,7 @@ public void registerAll(MetricSet metrics) throws IllegalArgumentException {
* @return a new {@link Counter}
*/
public Counter counter(String name) {
return getOrAdd(name, MetricBuilder.COUNTERS);
return getOrAdd(name, countersBuilder);
}

/**
Expand All @@ -121,7 +128,7 @@ public Counter counter(String name) {
* @return a new {@link Histogram}
*/
public Histogram histogram(String name) {
return getOrAdd(name, MetricBuilder.HISTOGRAMS);
return getOrAdd(name, histogramsBuilder);
}

/**
Expand All @@ -131,7 +138,7 @@ public Histogram histogram(String name) {
* @return a new {@link Meter}
*/
public Meter meter(String name) {
return getOrAdd(name, MetricBuilder.METERS);
return getOrAdd(name, metersBuilder);
}

/**
Expand All @@ -141,7 +148,7 @@ public Meter meter(String name) {
* @return a new {@link Timer}
*/
public Timer timer(String name) {
return getOrAdd(name, MetricBuilder.TIMERS);
return getOrAdd(name, timersBuilder);
}

/**
Expand Down Expand Up @@ -396,56 +403,56 @@ public Map<String, Metric> getMetrics() {
* A quick and easy way of capturing the notion of default metrics.
*/
private interface MetricBuilder<T extends Metric> {
MetricBuilder<Counter> COUNTERS = new MetricBuilder<Counter>() {
@Override
public Counter newMetric() {
return new Counter();
}
T newMetric();

@Override
public boolean isInstance(Metric metric) {
return Counter.class.isInstance(metric);
}
};
boolean isInstance(Metric metric);
}

MetricBuilder<Histogram> HISTOGRAMS = new MetricBuilder<Histogram>() {
@Override
public Histogram newMetric() {
return new Histogram(new ExponentiallyDecayingReservoir());
}
final MetricBuilder<Counter> countersBuilder = new MetricBuilder<Counter>() {
@Override
public Counter newMetric() {
return new Counter();
}

@Override
public boolean isInstance(Metric metric) {
return Histogram.class.isInstance(metric);
}
};
@Override
public boolean isInstance(Metric metric) {
return Counter.class.isInstance(metric);
}
};

MetricBuilder<Meter> METERS = new MetricBuilder<Meter>() {
@Override
public Meter newMetric() {
return new Meter();
}
final MetricBuilder<Histogram> histogramsBuilder = new MetricBuilder<Histogram>() {
@Override
public Histogram newMetric() {
return new Histogram(reservoirBuilder.newReservoir());
}

@Override
public boolean isInstance(Metric metric) {
return Meter.class.isInstance(metric);
}
};
@Override
public boolean isInstance(Metric metric) {
return Histogram.class.isInstance(metric);
}
};

MetricBuilder<Timer> TIMERS = new MetricBuilder<Timer>() {
@Override
public Timer newMetric() {
return new Timer();
}
final MetricBuilder<Meter> metersBuilder = new MetricBuilder<Meter>() {
@Override
public Meter newMetric() {
return new Meter();
}

@Override
public boolean isInstance(Metric metric) {
return Timer.class.isInstance(metric);
}
};
@Override
public boolean isInstance(Metric metric) {
return Meter.class.isInstance(metric);
}
};

T newMetric();
final MetricBuilder<Timer> timersBuilder = new MetricBuilder<Timer>() {
@Override
public Timer newMetric() {
return new Timer(reservoirBuilder.newReservoir());
}

boolean isInstance(Metric metric);
}
@Override
public boolean isInstance(Metric metric) {
return Timer.class.isInstance(metric);
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.codahale.metrics;

import java.util.concurrent.TimeUnit;

public abstract class ReservoirBuilder {
public static final class ExponentiallyDecayingReservoirBuilder extends ReservoirBuilder {
private final double alpha;
private final int size;
private final Clock clock;

public ExponentiallyDecayingReservoirBuilder(final int size, final double alpha, final Clock clock) {
this.size = size;
this.alpha = alpha;
this.clock = clock;
}

public ExponentiallyDecayingReservoirBuilder(final int size, final double alpha) {
this(size, alpha, Clock.defaultClock());
}

@Override
public Reservoir newReservoir() {
return new ExponentiallyDecayingReservoir(size, alpha, clock);
}
}

public static final class SlidingWindowReservoirBuilder extends ReservoirBuilder {
private final int size;

public SlidingWindowReservoirBuilder(final int size) {
this.size = size;
}

@Override
public final Reservoir newReservoir() {
return new SlidingWindowReservoir(size);
}
}

public static final class SlidingTimeWindowReservoirBuilder extends ReservoirBuilder {
private final long window;
private final TimeUnit windowUnit;
private final Clock clock;

public SlidingTimeWindowReservoirBuilder(final int window, final TimeUnit windowUnit, final Clock clock) {
this.window = window;
this.windowUnit = windowUnit;
this.clock = clock;
}

public SlidingTimeWindowReservoirBuilder(final int window, final TimeUnit windowUnit) {
this(window, windowUnit, Clock.defaultClock());
}

@Override
public final Reservoir newReservoir() {
return new SlidingTimeWindowReservoir(window, windowUnit, clock);
}
}

public static final class UniformReservoirBuilder extends ReservoirBuilder {
private final int size;

public UniformReservoirBuilder(final int size) {
this.size = size;
}

@Override
public final Reservoir newReservoir() {
return new UniformReservoir(size);
}
}

public abstract Reservoir newReservoir();
}