You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/08/22 09:07:03 UTC
svn commit: r1805734 - in /sling/trunk/bundles/commons/metrics-rrd4j/src:
main/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporter.java
test/java/org/apache/sling/commons/metrics/rrd4j/impl/ReporterTest.java
Author: rombert
Date: Tue Aug 22 09:07:03 2017
New Revision: 1805734
URL: http://svn.apache.org/viewvc?rev=1805734&view=rev
Log:
SLING-7071 - Rename metrics file on configuration change
Submitted-By: Marcel Reutegger
Modified:
sling/trunk/bundles/commons/metrics-rrd4j/src/main/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporter.java
sling/trunk/bundles/commons/metrics-rrd4j/src/test/java/org/apache/sling/commons/metrics/rrd4j/impl/ReporterTest.java
Modified: sling/trunk/bundles/commons/metrics-rrd4j/src/main/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporter.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/metrics-rrd4j/src/main/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporter.java?rev=1805734&r1=1805733&r2=1805734&view=diff
==============================================================================
--- sling/trunk/bundles/commons/metrics-rrd4j/src/main/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporter.java (original)
+++ sling/trunk/bundles/commons/metrics-rrd4j/src/main/java/org/apache/sling/commons/metrics/rrd4j/impl/RRD4JReporter.java Tue Aug 22 09:07:03 2017
@@ -36,6 +36,8 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -46,10 +48,13 @@ import java.util.SortedMap;
import java.util.concurrent.TimeUnit;
import static java.lang.String.join;
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
class RRD4JReporter extends ScheduledReporter {
private static final Logger LOGGER = LoggerFactory.getLogger(RRD4JReporter.class);
+
+ private static final String PROPERTIES_SUFFIX = ".properties";
static final int DEFAULT_STEP = 5;
private final Map<String, Integer> dictionary = new HashMap<>();
@@ -151,7 +156,7 @@ class RRD4JReporter extends ScheduledRep
super(registry, name, filter, rateUnit, durationUnit);
this.dictionary.putAll(dictionary);
this.rrdDB = createDB(rrdDef);
- storeDictionary(rrdDef.getPath() + ".properties");
+ storeDictionary(rrdDef.getPath() + PROPERTIES_SUFFIX);
}
@Override
@@ -170,31 +175,37 @@ class RRD4JReporter extends ScheduledRep
SortedMap<String, Histogram> histograms,
SortedMap<String, Meter> meters,
SortedMap<String, Timer> timers) {
-
+ 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);
for (Map.Entry<String, Gauge> entry : gauges.entrySet()) {
- update(sample, indexForName(entry.getKey()), entry.getValue());
+ reported += update(sample, indexForName(entry.getKey()), entry.getValue());
}
for (Map.Entry<String, Counter> entry : counters.entrySet()) {
- update(sample, indexForName(entry.getKey()), entry.getValue());
+ reported += update(sample, indexForName(entry.getKey()), entry.getValue());
}
for (Map.Entry<String, Histogram> entry : histograms.entrySet()) {
- update(sample, indexForName(entry.getKey()), entry.getValue());
+ reported += update(sample, indexForName(entry.getKey()), entry.getValue());
}
for (Map.Entry<String, Meter> entry : meters.entrySet()) {
- update(sample, indexForName(entry.getKey()), entry.getValue());
+ reported += update(sample, indexForName(entry.getKey()), entry.getValue());
}
for (Map.Entry<String, Timer> entry : timers.entrySet()) {
- update(sample, indexForName(entry.getKey()), entry.getValue());
+ reported += update(sample, indexForName(entry.getKey()), entry.getValue());
}
sample.update();
} catch (IOException e) {
LOGGER.warn("Unable to write sample to RRD", e);
+ } finally {
+ time = System.nanoTime() - time;
+ LOGGER.debug("{} out of {} metrics reported in {} \u03bcs",
+ reported, total, TimeUnit.NANOSECONDS.toMicros(time));
}
}
@@ -207,44 +218,49 @@ class RRD4JReporter extends ScheduledRep
return name.replaceAll(":", "_");
}
- private void update(Sample sample, int nameIdx, Gauge g) {
+ private int update(Sample sample, int nameIdx, Gauge g) {
if (nameIdx < 0) {
- return;
+ return 0;
}
Object value = g.getValue();
if (value instanceof Number) {
sample.setValue(nameIdx, ((Number) value).doubleValue());
+ return 1;
}
+ return 0;
}
- private void update(Sample sample, int nameIdx, Counter c) {
+ private int update(Sample sample, int nameIdx, Counter c) {
if (nameIdx < 0) {
- return;
+ return 0;
}
sample.setValue(nameIdx, c.getCount());
+ return 1;
}
- private void update(Sample sample, int nameIdx, Histogram h) {
+ private int update(Sample sample, int nameIdx, Histogram h) {
if (nameIdx < 0) {
- return;
+ return 0;
}
sample.setValue(nameIdx, h.getCount());
+ return 1;
}
- private void update(Sample sample, int nameIdx, Timer t) {
+ private int update(Sample sample, int nameIdx, Timer t) {
if (nameIdx < 0) {
- return;
+ return 0;
}
sample.setValue(nameIdx, t.getCount());
+ return 1;
}
- private void update(Sample sample, int nameIdx, Meter m) {
+ private int update(Sample sample, int nameIdx, Meter m) {
if (nameIdx < 0) {
- return;
+ return 0;
}
- LOGGER.debug("Sample: {} = {}", nameIdx, m.getCount());
sample.setValue(nameIdx, m.getCount());
+ return 1;
}
private void storeDictionary(String path) throws IOException {
@@ -274,10 +290,9 @@ class RRD4JReporter extends ScheduledRep
if (!db.getRrdDef().equals(definition)) {
// definition changed -> re-create DB
db.close();
- if (!dbFile.delete()) {
- throw new IOException("Unable to delete RRD file: " + dbFile.getPath());
- }
- LOGGER.warn("Configuration changed, recreating RRD file for metrics: " + dbFile.getPath());
+ File renamed = renameDB(dbFile);
+ LOGGER.info("Configuration changed, renamed existing RRD file to: {}",
+ renamed.getPath());
db = null;
}
}
@@ -286,4 +301,32 @@ class RRD4JReporter extends ScheduledRep
}
return db;
}
+
+ private File renameDB(File dbFile) throws IOException {
+ // find a suitable suffix
+ int idx = 0;
+ while (new File(dbFile.getPath() + suffix(idx)).exists()) {
+ idx++;
+ }
+ // rename rrd file
+ rename(dbFile.toPath(), dbFile.getName() + suffix(idx));
+ // rename properties file
+ rename(dbFile.toPath().resolveSibling(dbFile.getName() + PROPERTIES_SUFFIX),
+ dbFile.getName() + suffix(idx) + PROPERTIES_SUFFIX);
+
+ return new File(dbFile.getParentFile(), dbFile.getName() + suffix(idx));
+ }
+
+ private static String suffix(int idx) {
+ return "." + idx;
+ }
+
+ private void rename(Path path, String newName) throws IOException {
+ if (!Files.exists(path)) {
+ // nothing to rename
+ return;
+ }
+ Path target = path.resolveSibling(newName);
+ Files.move(path, target, REPLACE_EXISTING);
+ }
}
Modified: sling/trunk/bundles/commons/metrics-rrd4j/src/test/java/org/apache/sling/commons/metrics/rrd4j/impl/ReporterTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/metrics-rrd4j/src/test/java/org/apache/sling/commons/metrics/rrd4j/impl/ReporterTest.java?rev=1805734&r1=1805733&r2=1805734&view=diff
==============================================================================
--- sling/trunk/bundles/commons/metrics-rrd4j/src/test/java/org/apache/sling/commons/metrics/rrd4j/impl/ReporterTest.java (original)
+++ sling/trunk/bundles/commons/metrics-rrd4j/src/test/java/org/apache/sling/commons/metrics/rrd4j/impl/ReporterTest.java Tue Aug 22 09:07:03 2017
@@ -25,19 +25,21 @@ import java.util.Map;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
-import org.apache.sling.commons.metrics.rrd4j.impl.CodahaleMetricsReporter;
+import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.rrd4j.core.RrdDb;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class ReporterTest {
private static final File RRD = new File(new File("target", "metrics"), "metrics.rrd");
+ private static final File RRD_0 = new File(new File("target", "metrics"), "metrics.rrd.0");
private static final long TEST_VALUE = 42;
@@ -51,13 +53,10 @@ public class ReporterTest {
@Before
public void before() throws Exception {
RRD.delete();
+ RRD_0.delete();
context.registerService(MetricRegistry.class, registry, "name", "sling");
- Map<String, Object> properties = new HashMap<>();
- properties.put("step", 1L);
- properties.put("datasources", new String[]{"DS:sling_myMetric:GAUGE:300:0:U"});
- properties.put("archives", new String[]{"RRA:AVERAGE:0.5:1:60"});
- properties.put("path", RRD.getPath());
+ Map<String, Object> properties = newConfig();
context.registerInjectActivateService(reporter, properties);
registry.register("myMetric", new TestGauge(TEST_VALUE));
@@ -81,6 +80,19 @@ public class ReporterTest {
fail("RRD4J reporter did not update database in time");
}
+ @Test
+ public void reconfigure() throws Exception {
+ assertFalse(RRD_0.exists());
+ MockOsgi.deactivate(reporter, context.bundleContext());
+
+ // re-activate with changed configuration
+ Map<String, Object> properties = newConfig();
+ properties.put("step", 5L);
+ MockOsgi.activate(reporter, context.bundleContext(), properties);
+
+ assertTrue(RRD_0.exists());
+ }
+
private static final class TestGauge implements Gauge<Long> {
private final long value;
@@ -94,4 +106,13 @@ public class ReporterTest {
return value;
}
}
+
+ private static Map<String, Object> newConfig() {
+ Map<String, Object> properties = new HashMap<>();
+ properties.put("step", 1L);
+ properties.put("datasources", new String[]{"DS:sling_myMetric:GAUGE:300:0:U"});
+ properties.put("archives", new String[]{"RRA:AVERAGE:0.5:1:60"});
+ properties.put("path", RRD.getPath());
+ return properties;
+ }
}