diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/Counter.java b/modules/metrics/src/main/java/org/springside/modules/metrics/Counter.java index 02f136a1..f2ff65da 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/Counter.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/Counter.java @@ -7,16 +7,12 @@ import org.springside.modules.metrics.utils.Clock; public class Counter { private AtomicLong counter = new AtomicLong(0); - private long lastReportCounter = 0L; + private long lastReportCount = 0L; private Clock clock; private long startTime; private long lastReportTime; - public Counter() { - this(Clock.DEFAULT); - } - public Counter(Clock clock) { this.clock = clock; startTime = clock.getCurrentTime(); @@ -40,32 +36,25 @@ public class Counter { } public long reset() { - return counter.getAndSet(0); + long currentValue = counter.getAndSet(0); + lastReportCount = 0L; + startTime = clock.getCurrentTime(); + lastReportTime = startTime; + return currentValue; } - public long getCount() { - return counter.get(); - } + public CounterMetric getMetric() { + long currentCount = counter.get(); + long currentTime = clock.getCurrentTime(); - public double getLastRate() { - long currentCounter = counter.get(); - long reportTime = clock.getCurrentTime(); + CounterMetric metric = new CounterMetric(); + metric.count = currentCount; + metric.lastRate = ((currentCount - lastReportCount) * 1000) / (currentTime - lastReportTime); + metric.meanRate = ((currentCount * 1000) / (currentTime - startTime)); - double rate = 0.0; - if (currentCounter != 0) { - rate = ((currentCounter - lastReportCounter) / (reportTime - lastReportTime)) * 1000; - } - lastReportCounter = currentCounter; - lastReportTime = reportTime; + lastReportCount = currentCount; + lastReportTime = currentTime; - return rate; - } - - public double getMeanRate() { - if (counter.get() == 0) { - return 0.0; - } else { - return (counter.get() / (clock.getCurrentTime() - startTime)) * 1000; - } + return metric; } } diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/report/metrics/CounterMetric.java b/modules/metrics/src/main/java/org/springside/modules/metrics/CounterMetric.java similarity index 52% rename from modules/metrics/src/main/java/org/springside/modules/metrics/report/metrics/CounterMetric.java rename to modules/metrics/src/main/java/org/springside/modules/metrics/CounterMetric.java index 72adb6c2..0d23de1e 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/report/metrics/CounterMetric.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/CounterMetric.java @@ -1,7 +1,7 @@ -package org.springside.modules.metrics.report.metrics; +package org.springside.modules.metrics; public class CounterMetric { - public long coute; + public long count; public double lastRate; public double meanRate; } diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/Execution.java b/modules/metrics/src/main/java/org/springside/modules/metrics/Execution.java index d5bd8a2a..ef7d71cf 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/Execution.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/Execution.java @@ -3,6 +3,31 @@ package org.springside.modules.metrics; import org.springside.modules.metrics.utils.Clock; public class Execution { + private Counter counter; + private Histogram histogram; + private Clock clock; + + public Execution(Clock clock, Double[] pcts) { + this.clock = clock; + counter = new Counter(clock); + histogram = new Histogram(pcts); + } + + public ExecutiomTimer start() { + return new ExecutiomTimer(this, clock); + } + + private void update(long duration) { + histogram.update(duration); + counter.inc(); + } + + public ExecutionMetric getMetric() { + ExecutionMetric metric = new ExecutionMetric(); + metric.counter = counter.getMetric(); + metric.histogram = histogram.getMetric(); + return metric; + } public static class ExecutiomTimer { private final Execution execution; @@ -15,47 +40,9 @@ public class Execution { this.startTime = clock.getCurrentTime(); } - public long stop() { + public void stop() { final long elapsed = clock.getCurrentTime() - startTime; execution.update(elapsed); - return elapsed; } } - - private Counter counter; - private Histogram histogram; - private Clock clock; - - public Execution() { - this(Clock.DEFAULT); - } - - public Execution(Clock clock) { - this.clock = clock; - } - - public ExecutiomTimer start() { - return new ExecutiomTimer(this, clock); - } - - private void update(long duration) { - histogram.update(duration); - counter.inc(); - } - - public HistogramSnapshot getSnapshot() { - return histogram.getSnapshot(); - } - - public long getCount() { - return counter.getCount(); - } - - public double getLastRate() { - return counter.getLastRate(); - } - - public double getMeanRate() { - return counter.getMeanRate(); - } } diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/ExecutionMetric.java b/modules/metrics/src/main/java/org/springside/modules/metrics/ExecutionMetric.java new file mode 100644 index 00000000..5e5949e0 --- /dev/null +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/ExecutionMetric.java @@ -0,0 +1,6 @@ +package org.springside.modules.metrics; + +public class ExecutionMetric { + public CounterMetric counter; + public HistogramMetric histogram; +} diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/Histogram.java b/modules/metrics/src/main/java/org/springside/modules/metrics/Histogram.java index 34c11f3a..eb4b371d 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/Histogram.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/Histogram.java @@ -1,65 +1,79 @@ package org.springside.modules.metrics; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -import org.springside.modules.metrics.utils.Clock; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; public class Histogram { - // allow for this many duplicate ticks before overwriting measurements - private static final int COLLISION_BUFFER = 256; - // only trim on updating once every N - private static final int TRIM_THRESHOLD = 256; + private LinkedList measurements = new LinkedList(); + private Double[] pcts; - private final Clock clock; - private final ConcurrentSkipListMap measurements; - private final long window; - private final AtomicLong lastTick; - private final AtomicLong count; - - public Histogram(long window, TimeUnit windowUnit) { - this(window, windowUnit, Clock.DEFAULT); - } - - public Histogram(long window, TimeUnit windowUnit, Clock clock) { - this.clock = clock; - this.measurements = new ConcurrentSkipListMap(); - this.window = windowUnit.toMillis(window) * COLLISION_BUFFER; - this.lastTick = new AtomicLong(); - this.count = new AtomicLong(); + public Histogram(Double[] pcts) { + this.pcts = pcts; } public void update(long value) { - if ((count.incrementAndGet() % TRIM_THRESHOLD) == 0) { - trim(); - } - measurements.put(getTick(), value); - } - - public HistogramSnapshot getSnapshot() { - trim(); - return new HistogramSnapshot(measurements.values()); - } - - /** - * TODO:?? - */ - private long getTick() { - for (;;) { - final long oldTick = lastTick.get(); - final long tick = clock.getCurrentTime() * COLLISION_BUFFER; - - final long newTick = tick > oldTick ? tick : oldTick + 1; - if (lastTick.compareAndSet(oldTick, newTick)) { - return newTick; - } + synchronized (measurements) { + measurements.add(value); } } - private void trim() { - measurements.headMap(getTick() - window).clear(); + public HistogramMetric getMetric() { + + LinkedList snapshotList = measurements; + measurements = new LinkedList(); + + if (snapshotList.isEmpty()) { + return createEmptyMetric(); + } + + Collections.sort(snapshotList); + + int count = snapshotList.size(); + + HistogramMetric metric = new HistogramMetric(); + metric.min = snapshotList.get(0); + metric.max = snapshotList.get(count - 1); + + double sum = 0; + for (long value : snapshotList) { + sum += value; + } + metric.mean = sum / count; + + for (Double pct : pcts) { + + metric.pcts.put(pct, getPercent(snapshotList, count, pct)); + } + + return metric; } + public Long getPercent(List snapshotList, int count, double pct) { + + final double pos = pct * (count + 1); + + if (pos < 1) { + return snapshotList.get(0); + } + + if (pos >= count) { + return snapshotList.get(count - 1); + } + + return snapshotList.get((int) pos - 1); + } + + private HistogramMetric createEmptyMetric() { + HistogramMetric metric = new HistogramMetric(); + metric.min = 0; + metric.max = 0; + metric.mean = 0; + for (Double pct : pcts) { + metric.pcts.put(pct, 0L); + } + + return metric; + } } diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/HistogramMetric.java b/modules/metrics/src/main/java/org/springside/modules/metrics/HistogramMetric.java new file mode 100644 index 00000000..81a82c94 --- /dev/null +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/HistogramMetric.java @@ -0,0 +1,10 @@ +package org.springside.modules.metrics; + +import java.util.Map; + +public class HistogramMetric { + public long min; + public long max; + public double mean; + public Map pcts; +} diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/HistogramSnapshot.java b/modules/metrics/src/main/java/org/springside/modules/metrics/HistogramSnapshot.java deleted file mode 100644 index 268b5d8b..00000000 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/HistogramSnapshot.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.springside.modules.metrics; - -import static java.lang.Math.*; - -import java.util.Arrays; -import java.util.Collection; - -public class HistogramSnapshot { - - private final long[] values; - - /** - * Create a new {@link HistogramSnapshot} with the given values. - * - * @param values an unordered set of values in the reservoir - */ - public HistogramSnapshot(Collection values) { - final Object[] copy = values.toArray(); - this.values = new long[copy.length]; - for (int i = 0; i < copy.length; i++) { - this.values[i] = (Long) copy[i]; - } - Arrays.sort(this.values); - } - - /** - * Create a new {@link HistogramSnapshot} with the given values. - * - * @param values an unordered set of values in the reservoir - */ - public HistogramSnapshot(long[] values) { - this.values = Arrays.copyOf(values, values.length); - Arrays.sort(this.values); - } - - /** - * Returns the value at the given quantile. - * - * @param quantile a given quantile, in {@code [0..1]} - * @return the value in the distribution at {@code quantile} - */ - public double getValue(double quantile) { - if ((quantile < 0.0) || (quantile > 1.0)) { - throw new IllegalArgumentException(quantile + " is not in [0..1]"); - } - - if (values.length == 0) { - return 0.0; - } - - final double pos = quantile * (values.length + 1); - - if (pos < 1) { - return values[0]; - } - - if (pos >= values.length) { - return values[values.length - 1]; - } - - final double lower = values[(int) pos - 1]; - final double upper = values[(int) pos]; - return lower + ((pos - floor(pos)) * (upper - lower)); - } - - /** - * Returns the value at the 99th percentile in the distribution. - * - * @return the value at the 99th percentile - */ - public double get90th() { - return getValue(0.9); - } - - /** - * Returns the highest value in the snapshot. - * - * @return the highest value - */ - public long getMax() { - if (values.length == 0) { - return 0; - } - return values[values.length - 1]; - } - - /** - * Returns the lowest value in the snapshot. - * - * @return the lowest value - */ - public long getMin() { - if (values.length == 0) { - return 0; - } - return values[0]; - } - - /** - * Returns the arithmetic mean of the values in the snapshot. - * - * @return the arithmetic mean - */ - public double getMean() { - if (values.length == 0) { - return 0; - } - - double sum = 0; - for (long value : values) { - sum += value; - } - return sum / values.length; - } -} diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/MetricRegistry.java b/modules/metrics/src/main/java/org/springside/modules/metrics/MetricRegistry.java index b2992c1b..d05f1922 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/MetricRegistry.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/MetricRegistry.java @@ -1,5 +1,82 @@ package org.springside.modules.metrics; +import java.util.Collections; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.springside.modules.metrics.utils.Clock; + public class MetricRegistry { + public static final MetricRegistry INSTANCE = new MetricRegistry(); + + private Clock defaultClock = Clock.DEFAULT; + + private Double[] defaultPcts = new Double[] { 0.9 }; + + private ConcurrentMap metrics = new ConcurrentHashMap(); + + public static String name(String name, String... subNames) { + final StringBuilder builder = new StringBuilder(name); + if (subNames != null) { + for (String s : subNames) { + if ((s != null) && !s.isEmpty()) { + builder.append('.').append(s); + } + } + } + return builder.toString(); + } + + public Counter counter(String name) { + Counter counter = new Counter(defaultClock); + return (Counter) register(name, counter); + } + + public Histogram histogram(String name) { + Histogram histogram = new Histogram(defaultPcts); + return (Histogram) register(name, histogram); + } + + public Execution execution(String name) { + Execution execution = new Execution(defaultClock, defaultPcts); + return (Execution) register(name, execution); + } + + public Object register(String name, Object metric) { + return metrics.putIfAbsent(name, metric); + } + + public SortedMap getCounters() { + return getMetrics(Counter.class); + } + + public SortedMap getHistograms() { + return getMetrics(Histogram.class); + } + + public SortedMap getExecutions() { + return getMetrics(Execution.class); + } + + private SortedMap getMetrics(Class klass) { + final TreeMap result = new TreeMap(); + for (Map.Entry entry : metrics.entrySet()) { + if (klass.isInstance(entry.getValue())) { + result.put(entry.getKey(), (T) entry.getValue()); + } + } + return Collections.unmodifiableSortedMap(result); + } + + public void setDefaultClock(Clock clock) { + this.defaultClock = clock; + } + + public void setDefaultPcts(Double[] defaultPcts) { + this.defaultPcts = defaultPcts; + } } diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/report/ConsoleReporter.java b/modules/metrics/src/main/java/org/springside/modules/metrics/report/ConsoleReporter.java index 68b4a7ab..e0ab0717 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/report/ConsoleReporter.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/report/ConsoleReporter.java @@ -1,11 +1,13 @@ package org.springside.modules.metrics.report; import java.io.PrintStream; +import java.util.Date; import java.util.Map; -import java.util.SortedMap; +import java.util.Map.Entry; -import org.springside.modules.metrics.report.metrics.CounterMetric; -import org.springside.modules.metrics.report.metrics.HistogramMetric; +import org.springside.modules.metrics.CounterMetric; +import org.springside.modules.metrics.ExecutionMetric; +import org.springside.modules.metrics.HistogramMetric; public class ConsoleReporter implements Reporter { private static final int CONSOLE_WIDTH = 80; @@ -13,7 +15,12 @@ public class ConsoleReporter implements Reporter { private PrintStream output = System.out; @Override - public void report(SortedMap counters, SortedMap histograms) { + public void report(Map counters, Map histograms, + Map executions) { + + printWithBanner(new Date().toString(), '='); + output.println(); + if (!counters.isEmpty()) { printWithBanner("-- Counters", '-'); for (Map.Entry entry : counters.entrySet()) { @@ -22,6 +29,24 @@ public class ConsoleReporter implements Reporter { } output.println(); } + + if (!histograms.isEmpty()) { + printWithBanner("-- Histograms", '-'); + for (Map.Entry entry : histograms.entrySet()) { + output.println(entry.getKey()); + printHistogram(entry.getValue()); + } + output.println(); + } + + if (!executions.isEmpty()) { + printWithBanner("-- Executions", '-'); + for (Map.Entry entry : executions.entrySet()) { + output.println(entry.getKey()); + printExecution(entry.getValue()); + } + output.println(); + } } private void printWithBanner(String s, char c) { @@ -34,8 +59,23 @@ public class ConsoleReporter implements Reporter { } private void printCounter(CounterMetric counter) { - output.printf(" count = %d%n", counter.coute); - output.printf(" last rate = %2.2f events/%s%n", counter.lastRate); - output.printf(" mean rate = %2.2f events/%s%n", counter.meanRate); + output.printf(" count = %d%n", counter.count); + output.printf(" last rate = %2.2f /%s%n", counter.lastRate); + output.printf(" mean rate = %2.2f /%s%n", counter.meanRate); + } + + private void printHistogram(HistogramMetric histogram) { + output.printf(" min = %d%n", histogram.min); + output.printf(" max = %d%n", histogram.max); + output.printf(" mean = %2.2f%n", histogram.mean); + for (Entry pct : histogram.pcts.entrySet()) { + output.printf(" %d%% <= %2.2f%n", pct.getKey(), pct.getValue()); + } + + } + + private void printExecution(ExecutionMetric execution) { + printCounter(execution.counter); + printHistogram(execution.histogram); } } diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/report/ReportScheduler.java b/modules/metrics/src/main/java/org/springside/modules/metrics/report/ReportScheduler.java index cd1fa1c0..d3a03312 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/report/ReportScheduler.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/report/ReportScheduler.java @@ -1,20 +1,107 @@ package org.springside.modules.metrics.report; +import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import org.springside.modules.metrics.Counter; +import org.springside.modules.metrics.CounterMetric; +import org.springside.modules.metrics.Execution; +import org.springside.modules.metrics.ExecutionMetric; +import org.springside.modules.metrics.Histogram; +import org.springside.modules.metrics.HistogramMetric; import org.springside.modules.metrics.MetricRegistry; public class ReportScheduler { - + private static final String SCHEDULER_NAME = "metrics-reporter"; private List reporters; private MetricRegistry metricRegistry; + private ScheduledExecutorService executor; - public ReportScheduler(MetricRegistry metricRegistry, List repoters) { - this.reporters = repoters; + public ReportScheduler(MetricRegistry metricRegistry, Reporter... reporters) { + this(metricRegistry, Arrays.asList(reporters)); + } + + public ReportScheduler(MetricRegistry metricRegistry, List reporters) { + this.metricRegistry = metricRegistry; + this.reporters = reporters; + this.executor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory(SCHEDULER_NAME)); } public void report() { + SortedMap counterMap = metricRegistry.getCounters(); + SortedMap histogramMap = metricRegistry.getHistograms(); + SortedMap executionMap = metricRegistry.getExecutions(); + Map counterMetricMap = new LinkedHashMap(); + for (Entry entry : counterMap.entrySet()) { + counterMetricMap.put(entry.getKey(), entry.getValue().getMetric()); + } + + Map histogramMetricMap = new LinkedHashMap(); + for (Entry entry : histogramMap.entrySet()) { + histogramMetricMap.put(entry.getKey(), entry.getValue().getMetric()); + } + + Map executionMetricMap = new LinkedHashMap(); + for (Entry entry : executionMap.entrySet()) { + executionMetricMap.put(entry.getKey(), entry.getValue().getMetric()); + } + + for (Reporter reporter : reporters) { + reporter.report(counterMetricMap, histogramMetricMap, executionMetricMap); + } } + public void start(long period, TimeUnit unit) { + executor.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + report(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }, period, period, unit); + } + + public void stop() { + executor.shutdownNow(); + try { + executor.awaitTermination(1, TimeUnit.SECONDS); + } catch (InterruptedException ignored) { + // do nothing + } + } + + private static class NamedThreadFactory implements ThreadFactory { + private final ThreadGroup group; + private final AtomicInteger threadNumber = new AtomicInteger(1); + private final String namePrefix; + + private NamedThreadFactory(String name) { + final SecurityManager s = System.getSecurityManager(); + this.group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); + this.namePrefix = "metrics-" + name + "-thread-"; + } + + @Override + public Thread newThread(Runnable r) { + final Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); + t.setDaemon(true); + if (t.getPriority() != Thread.NORM_PRIORITY) { + t.setPriority(Thread.NORM_PRIORITY); + } + return t; + } + } } diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/report/Reporter.java b/modules/metrics/src/main/java/org/springside/modules/metrics/report/Reporter.java index c410ffc2..0f347b16 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/report/Reporter.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/report/Reporter.java @@ -1,10 +1,12 @@ package org.springside.modules.metrics.report; -import java.util.SortedMap; +import java.util.Map; -import org.springside.modules.metrics.report.metrics.CounterMetric; -import org.springside.modules.metrics.report.metrics.HistogramMetric; +import org.springside.modules.metrics.CounterMetric; +import org.springside.modules.metrics.ExecutionMetric; +import org.springside.modules.metrics.HistogramMetric; public interface Reporter { - void report(SortedMap counters, SortedMap histograms); + void report(Map counters, Map histograms, + Map executions); } diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/report/metrics/HistogramMetric.java b/modules/metrics/src/main/java/org/springside/modules/metrics/report/metrics/HistogramMetric.java deleted file mode 100644 index 3910a864..00000000 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/report/metrics/HistogramMetric.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springside.modules.metrics.report.metrics; - -public class HistogramMetric { - -} diff --git a/modules/metrics/src/main/java/org/springside/modules/metrics/utils/Clock.java b/modules/metrics/src/main/java/org/springside/modules/metrics/utils/Clock.java index 2219affa..cb1428e9 100644 --- a/modules/metrics/src/main/java/org/springside/modules/metrics/utils/Clock.java +++ b/modules/metrics/src/main/java/org/springside/modules/metrics/utils/Clock.java @@ -1,6 +1,5 @@ package org.springside.modules.metrics.utils; -import java.util.Date; /** * 日期提供者,使用它而不是直接取得系统时间,方便测试。 @@ -9,8 +8,6 @@ import java.util.Date; */ public interface Clock { - Date getCurrentDate(); - long getCurrentTime(); static final Clock DEFAULT = new DefaultDateProvider(); @@ -20,11 +17,6 @@ public interface Clock { */ public static class DefaultDateProvider implements Clock { - @Override - public Date getCurrentDate() { - return new Date(); - } - @Override public long getCurrentTime() { return System.currentTimeMillis(); @@ -39,31 +31,15 @@ public interface Clock { private long time; - public MockedDateProvider(Date date) { - this.time = date.getTime(); - } - public MockedDateProvider(long time) { this.time = time; } - @Override - public Date getCurrentDate() { - return new Date(time); - } - @Override public long getCurrentTime() { return time; } - /** - * 重新设置时间。 - */ - public void update(Date newDate) { - time = newDate.getTime(); - } - /** * 重新设置时间。 */ diff --git a/modules/metrics/src/test/java/org/springside/modules/metrics/CounterTest.java b/modules/metrics/src/test/java/org/springside/modules/metrics/CounterTest.java new file mode 100644 index 00000000..89da0593 --- /dev/null +++ b/modules/metrics/src/test/java/org/springside/modules/metrics/CounterTest.java @@ -0,0 +1,49 @@ +package org.springside.modules.metrics; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.springside.modules.metrics.utils.Clock.MockedDateProvider; + +public class CounterTest { + + @Test + public void normal() { + MockedDateProvider clock = new MockedDateProvider(0); + Counter counter = new Counter(clock); + + counter.inc(10); + counter.inc(20); + counter.inc(30); + clock.incrementTime(1000); + + CounterMetric metric = counter.getMetric(); + assertEquals(60, metric.count); + assertEquals(60d, metric.lastRate, 0); + assertEquals(60d, metric.meanRate, 0); + + counter.inc(20); + clock.incrementTime(1000); + metric = counter.getMetric(); + + assertEquals(80, metric.count); + assertEquals(20d, metric.lastRate, 0); + assertEquals(40d, metric.meanRate, 0); + } + + @Test + public void incAndDec() { + MockedDateProvider clock = new MockedDateProvider(0); + Counter counter = new Counter(clock); + + counter.inc(20); + counter.inc(); + counter.inc(); + counter.dec(10); + counter.dec(); + clock.incrementTime(1000); + + CounterMetric metric = counter.getMetric(); + assertEquals(11, metric.count); + } +}