changeset 1122:b33418b1f310

CsvMetricsCollectionAppender, CsvMetricsCollectionEncoderTest more tests
author Devel 2
date Wed, 03 Jun 2020 13:30:11 +0200
parents b45826b35c6e
children 9517e4cb9bd7
files stress-tester/src/main/java/com/passus/st/metric/CsvMetricsCollectionAppender.java stress-tester/src/main/java/com/passus/st/metric/CsvMetricsCollectionEncoder.java stress-tester/src/test/java/com/passus/st/metric/CsvMetricsCollectionEncoderTest.java
diffstat 3 files changed, 232 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/metric/CsvMetricsCollectionAppender.java	Wed Jun 03 13:30:11 2020 +0200
@@ -0,0 +1,196 @@
+package com.passus.st.metric;
+
+import com.passus.commons.Assert;
+import com.passus.commons.EncoderException;
+import com.passus.commons.annotations.Plugin;
+import com.passus.commons.metric.Metric;
+import com.passus.commons.metric.MetricsCollection;
+import com.passus.config.Configuration;
+import com.passus.config.ConfigurationContext;
+import com.passus.config.annotations.NodeDefinitionCreate;
+import com.passus.config.schema.NodeDefinition;
+import com.passus.config.schema.NodeDefinitionCreator;
+import com.passus.st.plugin.PluginConstants;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static com.passus.config.schema.ConfigurationSchemaBuilder.mapDef;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.tupleDef;
+import static com.passus.st.config.CommonNodeDefs.BOOLEAN_DEF;
+import static com.passus.st.config.CommonNodeDefs.STRING_DEF;
+
+@NodeDefinitionCreate(CsvMetricsCollectionAppender.CsvMetricsCollectionAppenderNodeDefCreator.class)
+@Plugin(name = CsvMetricsCollectionAppender.TYPE, category = PluginConstants.CATEGORY_METRICS_COLLECTION_APPENDER)
+public class CsvMetricsCollectionAppender implements MetricsCollectionAppender {
+
+    public static final String TYPE = "csv";
+
+    private static final Logger LOGGER = LogManager.getLogger(CsvMetricsCollectionAppender.class);
+
+    private Map<String, CsvFile> files = new HashMap<>();
+
+    private int bufferSize = 512;
+
+    private String encoding = "UTF-8";
+
+    private String dirName;
+
+    private File dir;
+
+    private volatile boolean started = false;
+
+    private String name;
+
+    @Override
+    public String getType() {
+        return TYPE;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        Assert.notNull(name, "name");
+        this.name = name;
+    }
+
+    public String getDirName() {
+        return dirName;
+    }
+
+    public void setDirName(String dirName) {
+        this.dirName = dirName;
+    }
+
+    @Override
+    public void configure(Configuration config, ConfigurationContext context) {
+        setDirName(config.getString("dir"));
+    }
+
+    @Override
+    public boolean isStarted() {
+        return started;
+    }
+
+    @Override
+    public void start() {
+        if (started) {
+            return;
+        }
+
+        dir = new File(dirName);
+        started = true;
+    }
+
+    @Override
+    public void stop() {
+        if (!started) {
+            return;
+        }
+
+        for (CsvFile csvFile : files.values()) {
+            csvFile.close();
+        }
+
+        dir = null;
+    }
+
+    @Override
+    public void handle(MetricsCollection mc) {
+        if (!started) {
+            return;
+        }
+
+        List<Metric> metrics = mc.getMetrics();
+
+        try {
+            for (Metric metric : metrics) {
+                CsvFile csvFile = files.get(metric.getName());
+                if (csvFile == null) {
+                    csvFile = new CsvFile(metric.getName(), dir, bufferSize, encoding);
+                    csvFile.encodeHeadersIfNeeded(mc);
+                    files.put(metric.getName(), csvFile);
+                }
+
+                csvFile.handle(mc);
+            }
+        } catch (Exception e) {
+            LOGGER.error("Unable to write metrics. " + e.getMessage(), e);
+        }
+    }
+
+    private static class CsvFile {
+
+        private final CsvMetricsCollectionEncoder encoder;
+
+        private final File file;
+
+        private final Writer writer;
+
+        private CsvFile(String metricName, File dir, int bufferSize, String encoding) throws IOException {
+            this.encoder = new CsvMetricsCollectionEncoder(metricName);
+            this.file = new File(dir, metricName + ".csv");
+
+            if (!file.exists()) {
+                if (!file.createNewFile()) {
+                    throw new IOException("Unable to create file '" + file + "' ");
+                }
+            }
+
+            Writer osWriter = new OutputStreamWriter(new FileOutputStream(file, true), encoding);
+            if (bufferSize > 0) {
+                writer = new BufferedWriter(osWriter, bufferSize);
+            } else {
+                writer = osWriter;
+            }
+        }
+
+        private void close() {
+            try {
+                writer.close();
+            } catch (IOException ignore) {
+
+            }
+        }
+
+        private void write(String value) throws IOException {
+            if (value != null && value.length() > 0) {
+                writer.write(value);
+                writer.write("\n");
+                writer.flush();
+            }
+        }
+
+        private void encodeHeadersIfNeeded(MetricsCollection mc) throws IOException {
+            if (file.length() == 0) {
+                String encoded = encoder.encodeHeaders(mc);
+                write(encoded);
+            }
+        }
+
+        private void handle(MetricsCollection mc) throws IOException, EncoderException {
+            String encoded = encoder.encode(mc);
+            write(encoded);
+        }
+
+    }
+
+    public static final class CsvMetricsCollectionAppenderNodeDefCreator implements NodeDefinitionCreator {
+
+        @Override
+        public NodeDefinition create() {
+            return mapDef(
+                    tupleDef("active", BOOLEAN_DEF).setRequired(false),
+                    tupleDef("dir", STRING_DEF)
+            );
+        }
+
+    }
+}
--- a/stress-tester/src/main/java/com/passus/st/metric/CsvMetricsCollectionEncoder.java	Wed Jun 03 10:30:48 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/metric/CsvMetricsCollectionEncoder.java	Wed Jun 03 13:30:11 2020 +0200
@@ -36,6 +36,10 @@
         this.metricName = metricName;
     }
 
+    public String getMetricName() {
+        return metricName;
+    }
+
     public char getDelimiter() {
         return delimiter;
     }
@@ -100,6 +104,27 @@
         }
     }
 
+    public String encodeHeaders(MetricsCollection mc) {
+        Metric metric = mc.getMetric(metricName);
+        if (metric == null) {
+            return null;
+        }
+
+        sb1.setLength(0);
+
+        appendStringValue("startTime", sb1);
+        sb1.append(delimiter);
+
+        appendStringValue("endTime", sb1);
+
+        Set<String> names = metric.getAttributesName();
+        for (String name : names) {
+            sb1.append(delimiter);
+            appendStringValue(name, sb1);
+        }
+        return sb1.toString();
+    }
+
     @Override
     public String encode(MetricsCollection mc) throws EncoderException {
         Metric metric = mc.getMetric(metricName);
--- a/stress-tester/src/test/java/com/passus/st/metric/CsvMetricsCollectionEncoderTest.java	Wed Jun 03 10:30:48 2020 +0200
+++ b/stress-tester/src/test/java/com/passus/st/metric/CsvMetricsCollectionEncoderTest.java	Wed Jun 03 13:30:11 2020 +0200
@@ -21,4 +21,15 @@
         assertEquals(expected, encoder.encode(coll));
     }
 
+    @Test
+    public void testEncodeHeaders() {
+        Metric metric = new TestMetric();
+
+        MetricsCollection coll = new MetricsCollection(0, 1, Arrays.asList(metric));
+        CsvMetricsCollectionEncoder encoder = new CsvMetricsCollectionEncoder("test");
+
+        String expected = "startTime,endTime,string,map,int";
+        assertEquals(expected, encoder.encodeHeaders(coll));
+    }
+
 }
\ No newline at end of file