From d576b7d61c36d1b76d0d820f4bbc5149dd5fef84 Mon Sep 17 00:00:00 2001 From: Matthew Bogner Date: Mon, 17 Jun 2013 16:43:08 -0500 Subject: [PATCH 1/2] Add option to translate a yammer timer (or histogram) to a gauge when being sent to statsd --- .../metrics/reporting/StatsdReporter.java | 13 ++++- .../metrics/reporting/StatsdReporterTest.java | 50 +++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/bealetech/metrics/reporting/StatsdReporter.java b/src/main/java/com/bealetech/metrics/reporting/StatsdReporter.java index 6d4cdb2..cfc3dff 100644 --- a/src/main/java/com/bealetech/metrics/reporting/StatsdReporter.java +++ b/src/main/java/com/bealetech/metrics/reporting/StatsdReporter.java @@ -48,6 +48,9 @@ public static enum StatType { COUNTER, TIMER, GAUGE } private boolean prependNewline = false; private boolean printVMMetrics = true; + private boolean shouldTranslateTimersToGauges = true; // Statsd rewrites timers with more info, causing a potential explosion in + // the number of metrics being pushed from statsd to graphite if you have a + // lot of timers or histograms. See: https://github.com/etsy/statsd/blob/master/docs/metric_types.md#timing public interface UDPSocketProvider { DatagramSocket get() throws Exception; @@ -108,6 +111,14 @@ public void setPrintVMMetrics(boolean printVMMetrics) { this.printVMMetrics = printVMMetrics; } + public boolean isShouldTranslateTimersToGauges() { + return shouldTranslateTimersToGauges; + } + + public void setShouldTranslateTimersToGauges(boolean shouldTranslateTimersToGauges) { + this.shouldTranslateTimersToGauges = shouldTranslateTimersToGauges; + } + @Override public void run() { DatagramSocket socket = null; @@ -303,7 +314,7 @@ protected void sendData(String name, String value, StatType statType) { statTypeStr = "g"; break; case TIMER: - statTypeStr = "ms"; + statTypeStr = shouldTranslateTimersToGauges ? "g" : "ms"; break; } diff --git a/src/test/java/com/bealetech/metrics/reporting/StatsdReporterTest.java b/src/test/java/com/bealetech/metrics/reporting/StatsdReporterTest.java index e1906b6..fce7713 100644 --- a/src/test/java/com/bealetech/metrics/reporting/StatsdReporterTest.java +++ b/src/test/java/com/bealetech/metrics/reporting/StatsdReporterTest.java @@ -16,7 +16,6 @@ package com.bealetech.metrics.reporting; import com.yammer.metrics.core.*; -import com.yammer.metrics.reporting.AbstractPollingReporter; import com.yammer.metrics.stats.Snapshot; import org.junit.Before; import org.junit.Test; @@ -39,7 +38,7 @@ public class StatsdReporterTest { protected final Clock clock = mock(Clock.class); - protected AbstractPollingReporter reporter; + protected StatsdReporter reporter; protected TestMetricsRegistry registry; protected DatagramPacket packet; @@ -59,7 +58,7 @@ public void init() throws Exception { reporter = createReporter(registry, clock); } - protected AbstractPollingReporter createReporter(MetricsRegistry registry, Clock clock) throws Exception { + protected StatsdReporter createReporter(MetricsRegistry registry, Clock clock) throws Exception { final DatagramSocket socket = mock(DatagramSocket.class); final StatsdReporter.UDPSocketProvider provider = mock(StatsdReporter.UDPSocketProvider.class); when(provider.get()).thenReturn(socket); @@ -75,12 +74,22 @@ protected AbstractPollingReporter createReporter(MetricsRegistry registry, Clock } protected void assertReporterOutput(Callable action, String... expected) throws Exception { + assertReporterOutput(action, false, expected); + } + + protected void assertReporterOutput(Callable action, boolean shouldTranslateTimersToGauges, String... expected) throws Exception { // Invoke the callable to trigger (ie, mark()/inc()/etc) and return the metric final T metric = action.call(); try { // Add the metric to the registry, run the reporter and flush the result registry.add(new MetricName(Object.class, "metric"), metric); - reporter.run(); + boolean oldTimerTranslationConfig = reporter.isShouldTranslateTimersToGauges(); + try { + reporter.setShouldTranslateTimersToGauges(shouldTranslateTimersToGauges); + reporter.run(); + } finally { + reporter.setShouldTranslateTimersToGauges(oldTimerTranslationConfig); + } String packetData = new String(packet.getData()); final String[] lines = packetData.split("\r?\n|\r"); @@ -125,6 +134,26 @@ public String[] expectedTimerResult() { }; } + public String[] expectedTranslatedTimerResult() { + return new String[]{ + "prefix.java.lang.Object.metric.count:1|g", + "prefix.java.lang.Object.metric.meanRate:2.00|g", + "prefix.java.lang.Object.metric.1MinuteRate:1.00|g", + "prefix.java.lang.Object.metric.5MinuteRate:5.00|g", + "prefix.java.lang.Object.metric.15MinuteRate:15.00|g", + "prefix.java.lang.Object.metric.min:1.00|g", + "prefix.java.lang.Object.metric.max:3.00|g", + "prefix.java.lang.Object.metric.mean:2.00|g", + "prefix.java.lang.Object.metric.stddev:1.50|g", + "prefix.java.lang.Object.metric.median:0.50|g", + "prefix.java.lang.Object.metric.75percentile:0.75|g", + "prefix.java.lang.Object.metric.95percentile:0.95|g", + "prefix.java.lang.Object.metric.98percentile:0.98|g", + "prefix.java.lang.Object.metric.99percentile:0.99|g", + "prefix.java.lang.Object.metric.999percentile:1.00|g" + }; + } + public String[] expectedMeterResult() { return new String[]{ "prefix.java.lang.Object.metric.count:1|g", @@ -218,6 +247,19 @@ public Gauge call() throws Exception { expectedGaugeResult(value)); } + @Test + public final void timerWithTranslatedOutput() throws Exception { + assertReporterOutput( + new Callable() { + @Override + public Timer call() throws Exception { + return createTimer(); + } + }, + true, + expectedTranslatedTimerResult()); + } + static Counter createCounter(long count) throws Exception { final Counter mock = mock(Counter.class); when(mock.count()).thenReturn(count); From debb06d6f0d52f6c6843cbd34054c76a3074ae12 Mon Sep 17 00:00:00 2001 From: Matthew Bogner Date: Tue, 18 Jun 2013 07:40:05 -0500 Subject: [PATCH 2/2] =?UTF-8?q?whoops=E2=80=A6=20should=20be=20disabled=20?= =?UTF-8?q?by=20default=20to=20preserve=20backwards=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bealetech/metrics/reporting/StatsdReporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bealetech/metrics/reporting/StatsdReporter.java b/src/main/java/com/bealetech/metrics/reporting/StatsdReporter.java index cfc3dff..ab74f5d 100644 --- a/src/main/java/com/bealetech/metrics/reporting/StatsdReporter.java +++ b/src/main/java/com/bealetech/metrics/reporting/StatsdReporter.java @@ -48,7 +48,7 @@ public static enum StatType { COUNTER, TIMER, GAUGE } private boolean prependNewline = false; private boolean printVMMetrics = true; - private boolean shouldTranslateTimersToGauges = true; // Statsd rewrites timers with more info, causing a potential explosion in + private boolean shouldTranslateTimersToGauges = false; // Statsd rewrites timers with more info, causing a potential explosion in // the number of metrics being pushed from statsd to graphite if you have a // lot of timers or histograms. See: https://github.com/etsy/statsd/blob/master/docs/metric_types.md#timing