SLING-7222 - Too frequent samples
authorChetan Mehrotra <chetanm@apache.org>
Tue, 31 Oct 2017 14:31:39 +0000 (20:01 +0530)
committerChetan Mehrotra <chetanm@apache.org>
Tue, 31 Oct 2017 14:31:39 +0000 (20:01 +0530)
Apply patch from Marcel

src/main/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporter.java
src/test/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporterTest.java [new file with mode: 0644]

index a0caef4..40dbd7c 100644 (file)
@@ -62,6 +62,7 @@ class RRD4JReporter extends ScheduledReporter {
 
     private final Map<String, Integer> dictionary = new HashMap<>();
     private final RrdDb rrdDB;
+    private long lastSampleTime;
 
     static Builder forRegistry(MetricRegistry metricRegistry) {
         return new Builder(metricRegistry);
@@ -212,11 +213,16 @@ class RRD4JReporter extends ScheduledReporter {
                        SortedMap<String, Histogram> histograms,
                        SortedMap<String, Meter> meters,
                        SortedMap<String, Timer> timers) {
+        long sampleTime = System.currentTimeMillis() / 1000;
+        if (sampleTime <= lastSampleTime) {
+            // sample at most once a second
+            return;
+        }
         long time = System.nanoTime();
         int total = gauges.size() + counters.size() + histograms.size() + meters.size() + timers.size();
         int reported = 0;
         try {
-            Sample sample = rrdDB.createSample(System.currentTimeMillis() / 1000);
+            Sample sample = rrdDB.createSample(sampleTime);
             for (Map.Entry<String, Gauge> entry : gauges.entrySet()) {
                 reported += update(sample, entry.getKey(), entry.getValue());
             }
@@ -240,6 +246,7 @@ class RRD4JReporter extends ScheduledReporter {
         } catch (IOException e) {
             LOGGER.warn("Unable to write sample to RRD", e);
         } finally {
+            lastSampleTime = sampleTime;
             time = System.nanoTime() - time;
             LOGGER.debug("{} out of {} metrics reported in {} \u03bcs",
                     reported, total, TimeUnit.NANOSECONDS.toMicros(time));
diff --git a/src/test/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporterTest.java b/src/test/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporterTest.java
new file mode 100644 (file)
index 0000000..922500a
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.metrics.rrd4j.impl;
+
+import java.io.File;
+import java.io.IOException;
+
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.MetricRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RRD4JReporterTest {
+
+    private static final File RRD = new File(new File("target", "metrics"), "metrics.rrd");
+
+    private MetricRegistry registry = new MetricRegistry();
+    private RRD4JReporter reporter;
+
+    @Before
+    public void before() throws IOException {
+        RRD.delete();
+        registry.register("myMetric", new TestGauge(42));
+        reporter = RRD4JReporter.forRegistry(registry)
+                .withPath(RRD)
+                .withArchives(new String[]{"RRA:AVERAGE:0.5:1:60"})
+                .withDatasources(new String[]{"DS:sling_myMetric:GAUGE:300:0:U"})
+                .withStep(1)
+                .build();
+    }
+
+    @After
+    public void after() {
+        reporter.close();
+        RRD.delete();
+    }
+
+    @Test
+    public void tooFrequentSamples() {
+        reporter.report();
+        reporter.report();
+    }
+
+    private static final class TestGauge implements Gauge<Long> {
+
+        private final long value;
+
+        TestGauge(long value) {
+            this.value = value;
+        }
+
+        @Override
+        public Long getValue() {
+            return value;
+        }
+    }
+}
+