package com.signalfx.codahale.metrics; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.junit.Test; import com.codahale.metrics.Counter; import com.codahale.metrics.Gauge; import com.codahale.metrics.Metric; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; import com.google.common.collect.ImmutableSet; import com.signalfx.codahale.reporter.IncrementalCounter; import com.signalfx.codahale.reporter.MetricMetadata; import com.signalfx.codahale.reporter.SfUtil; import com.signalfx.codahale.reporter.SignalFxReporter; import com.signalfx.metrics.auth.StaticAuthToken; import com.signalfx.metrics.connection.StaticDataPointReceiverFactory; import com.signalfx.metrics.connection.StoredDataPointReceiver; import com.signalfx.metrics.protobuf.SignalFxProtocolBuffers; public class SignalFxReporterTest { @Test public void testReporter() throws InterruptedException { StoredDataPointReceiver dbank = new StoredDataPointReceiver(); assertEquals(0, dbank.addDataPoints.size()); MetricRegistry metricRegistery = new MetricRegistry(); SignalFxReporter reporter = new SignalFxReporter.Builder(metricRegistery, new StaticAuthToken(""), "myserver") .setDataPointReceiverFactory(new StaticDataPointReceiverFactory(dbank)) .setDetailsToAdd(ImmutableSet.of(SignalFxReporter.MetricDetails.COUNT, SignalFxReporter.MetricDetails.MIN, SignalFxReporter.MetricDetails.MAX)) .build(); Metric gauge = metricRegistery.register("gauge", new Gauge<Integer>() { @Override public Integer getValue() { return 1; } }); final MetricMetadata metricMetadata = reporter.getMetricMetadata(); metricMetadata.forMetric(metricRegistery.counter("counter")) .withMetricName("newname") .withSourceName("newsource") .withMetricType(SignalFxProtocolBuffers.MetricType.GAUGE); metricMetadata.forMetric(metricRegistery.counter("counter2")) .withMetricName("newname2"); metricRegistery.counter("counter").inc(); metricRegistery.counter("counter").inc(); metricRegistery.timer("atimer").time().close(); reporter.report(); assertEquals(6, dbank.addDataPoints.size()); assertEquals("newname", dbank.addDataPoints.get(1).getMetric()); assertEquals("newsource", dbank.addDataPoints.get(1).getDimensions(0).getValue()); assertEquals("sf_source", dbank.addDataPoints.get(1).getDimensions(0).getKey()); assertEquals(SignalFxProtocolBuffers.MetricType.GAUGE, dbank.registeredMetrics.get( "newname")); assertEquals(SignalFxProtocolBuffers.MetricType.CUMULATIVE_COUNTER, dbank.registeredMetrics.get( "atimer.count")); assertEquals(SignalFxProtocolBuffers.MetricType.GAUGE, dbank.registeredMetrics.get( "atimer.max")); assertEquals(2, dbank.lastValueFor("newsource", "newname").getIntValue()); assertNotNull(dbank.lastValueFor("myserver", "atimer.count")); dbank.addDataPoints.clear(); metricMetadata.forMetric(metricRegistery.counter("raw_counter")) .withMetricType(SignalFxProtocolBuffers.MetricType.COUNTER); SfUtil.cumulativeCounter(metricRegistery, "cumulative_counter_callback", metricMetadata, new Gauge<Long>() { private long i = 0; @Override public Long getValue() { return i++; } }); Counter distributedCounter = metricMetadata .forMetric(new IncrementalCounter()) .withMetricName("user_login.hits") .withSourceName("webpage") .register(metricRegistery); assertNotNull(metricRegistery.getCounters().get("webpage.user_login.hits")); distributedCounter.inc(123); metricRegistery.counter("raw_counter").inc(10); metricMetadata.forBuilder(IncrementalCounter.Builder.INSTANCE) .withSourceName("asource") .withMetricName("name") .createOrGet(metricRegistery) .inc(1); try { metricMetadata.forBuilder(SettableLongGauge.Builder.INSTANCE) .withSourceName("asource") .withMetricName("name") .createOrGet(metricRegistery); throw new RuntimeException("We shouldn't be able to make it with the same name and different type"); } catch (IllegalArgumentException e) { // Expected } reporter.report(); assertEquals(10, dbank.addDataPoints.size()); assertEquals(10, dbank.lastValueFor("myserver", "raw_counter").getIntValue()); assertEquals(0, dbank.lastValueFor("myserver", "cumulative_counter_callback").getIntValue()); assertEquals(123, dbank.lastValueFor("webpage", "user_login.hits").getIntValue()); assertEquals(1, dbank.lastValueFor("asource", "name").getIntValue()); assertEquals(2, dbank.lastValueFor("newsource", "newname").getIntValue()); distributedCounter.inc(1); distributedCounter.inc(3); assertEquals(SignalFxProtocolBuffers.MetricType.COUNTER, dbank.registeredMetrics.get("user_login.hits")); assertEquals(SignalFxProtocolBuffers.MetricType.COUNTER, dbank.registeredMetrics.get("raw_counter")); assertEquals(SignalFxProtocolBuffers.MetricType.CUMULATIVE_COUNTER, dbank.registeredMetrics.get("cumulative_counter_callback")); metricRegistery.counter("raw_counter").inc(14); dbank.addDataPoints.clear(); metricMetadata.forBuilder(IncrementalCounter.Builder.INSTANCE) .withSourceName("asource") .withMetricName("name") .createOrGet(metricRegistery) .inc(3); assertEquals(0, SfUtil.removeMetrics(metricRegistery, new Counter())); assertEquals(2, SfUtil.removeMetrics(metricRegistery, gauge, metricRegistery.counter("counter"))); assertEquals(true, dbank.clearValues("newsource", "newname")); assertEquals(false, dbank.clearValues("newsource", "newname")); reporter.report(); assertEquals(8, dbank.addDataPoints.size()); assertEquals(0, dbank.valuesFor("newsource", "newname").size()); // Users have to use an IncrementalCounter if they want to see the count value of 14 each time assertEquals(24, dbank.lastValueFor("myserver", "raw_counter").getIntValue()); assertEquals(1, dbank.lastValueFor("myserver", "cumulative_counter_callback").getIntValue()); assertEquals(4, dbank.lastValueFor("webpage", "user_login.hits").getIntValue()); assertEquals(3, dbank.lastValueFor("asource", "name").getIntValue()); try { metricMetadata.forBuilder(IncrementalCounter.Builder.INSTANCE).withSourceName("asource") .withMetricName("name") .withMetricType(SignalFxProtocolBuffers.MetricType.GAUGE) .createOrGet(metricRegistery); throw new RuntimeException("I expect an error if it's a gauge"); } catch (IllegalArgumentException e) { // Expected } metricMetadata.forMetric(new Counter()) .withSourceName("webpage") .withMetricName("countstuff") .register(metricRegistery); try { metricMetadata.forBuilder(IncrementalCounter.Builder.INSTANCE) .withSourceName("webpage") .withMetricName("countstuff") .createOrGet(metricRegistery); throw new RuntimeException("I expect an already registered metric on this name"); } catch (IllegalArgumentException e) { // Expected } Timer t = metricMetadata.forBuilder(MetricBuilder.TIMERS) .withMetricName("request_time") .withDimension("storename", "electronics") .createOrGet(metricRegistery); Timer.Context c = t.time(); try { System.out.println("Doing store things"); } finally { c.close(); } // Java 7 alternative: // try (Timer.Context ignored = t.time()) { // System.out.println("Doing store things"); // } } }