Skip to content
Snippets Groups Projects
Commit eae751ff authored by Reiner Jung's avatar Reiner Jung
Browse files

Updated result analysis tool.

parent f12020c6
No related branches found
No related tags found
No related merge requests found
Showing
with 498 additions and 301 deletions
...@@ -63,15 +63,18 @@ pipeline { ...@@ -63,15 +63,18 @@ pipeline {
sshagent(credentials: ['kieker-irl-key']) { sshagent(credentials: ['kieker-irl-key']) {
unstash 'yaml' unstash 'yaml'
sh ''' sh '''
echo "put kieker-python-results.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL} mkdir all
echo "put kieker-java-results.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL} cd all
echo "put open-telementry-results.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL} sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/kieker-java.yaml
echo "put insepct-it-results.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL} sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/kieker-python.yaml
# sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/all-results.json # sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/opentelemetry.yaml
# compile-results/bin/compile-results results-Kieker/results-text.csv all-results.json # sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/inspectit.yaml
# echo "put all-results.json" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL} cd ..
# echo "put partial-results.json" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL} compile-results/bin/compile-results -i *-results.yaml -l all -t all -j all -w 100
# echo "put relative-results.json" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL} cd all
echo "put *.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
echo "put *.html" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
echo "put *.json" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
''' '''
} }
} }
......
...@@ -55,6 +55,12 @@ info "----------------------------------" ...@@ -55,6 +55,12 @@ info "----------------------------------"
info "Setup..." info "Setup..."
info "----------------------------------" info "----------------------------------"
# This is necessary, as the framework name is originally
# derived from the directory the script is sitting in, but
# Kieker supports multiple languages and has multiple
# sub directories for each programming language.
export FRAMEWORK_NAME="kieker-${FRAMEWORK_NAME}"
cd "${BASE_DIR}" cd "${BASE_DIR}"
# load agent # load agent
......
...@@ -55,6 +55,12 @@ info "----------------------------------" ...@@ -55,6 +55,12 @@ info "----------------------------------"
info "Setup..." info "Setup..."
info "----------------------------------" info "----------------------------------"
# This is necessary, as the framework name is originally
# derived from the directory the script is sitting in, but
# Kieker supports multiple languages and has multiple
# sub directories for each programming language.
export FRAMEWORK_NAME="kieker-${FRAMEWORK_NAME}"
cd "${BASE_DIR}" cd "${BASE_DIR}"
# load agent # load agent
......
...@@ -90,19 +90,27 @@ print(resultstext) ...@@ -90,19 +90,27 @@ print(resultstext)
currentTime <- as.numeric(Sys.time()) currentTime <- as.numeric(Sys.time())
mktext <- function(value) {
if (is.na(value)) {
return(".NAN")
} else {
return(format(value, scientific=TRUE))
}
}
write(paste("kind:", configs.framework_name), file=out_yaml_fn,append=FALSE) write(paste("kind:", configs.framework_name), file=out_yaml_fn,append=FALSE)
write("experiments:", file=out_yaml_fn, append=TRUE) write("experiments:", file=out_yaml_fn, append=TRUE)
write(paste("- timestamp:", currentTime), file=out_yaml_fn, append=TRUE) write(paste("- timestamp:", currentTime), file=out_yaml_fn, append=TRUE)
write(" measurements:", file=out_yaml_fn, append=TRUE) write(" measurements:", file=out_yaml_fn, append=TRUE)
for (writer_idx in (1:(numberOfWriters))) { for (writer_idx in (1:(numberOfWriters))) {
write(paste(" ", configs.labels[writer_idx], ": [", write(paste(" ", configs.labels[writer_idx], ": [",
format(printvalues["mean",writer_idx], scientific=TRUE), ",", mktext(printvalues["mean",writer_idx]), ",",
format(printvalues["sd",writer_idx], scientific=TRUE), ",", mktext(printvalues["sd",writer_idx]), ",",
format(printvalues["ci95%",writer_idx], scientific=TRUE), ",", mktext(printvalues["ci95%",writer_idx]), ",",
format(printvalues["md25%",writer_idx], scientific=TRUE), ",", mktext(printvalues["md25%",writer_idx]), ",",
format(printvalues["md50%",writer_idx], scientific=TRUE), ",", mktext(printvalues["md50%",writer_idx]), ",",
format(printvalues["md75%",writer_idx], scientific=TRUE), ",", mktext(printvalues["md75%",writer_idx]), ",",
format(printvalues["max",writer_idx], scientific=TRUE), ",", mktext(printvalues["max",writer_idx]), ",",
format(printvalues["min",writer_idx], scientific=TRUE), "]"), file=out_yaml_fn, append=TRUE) mktext(printvalues["min",writer_idx]), "]"), file=out_yaml_fn, append=TRUE)
} }
# end # end
/**
*
*/
package moobench.tools.results;
import java.util.List;
import java.util.Map;
import moobench.tools.results.data.Chart;
import moobench.tools.results.data.Experiment;
import moobench.tools.results.data.ExperimentLog;
import moobench.tools.results.data.Measurements;
import moobench.tools.results.data.ValueTuple;
import teetime.stage.basic.AbstractTransformation;
/**
* @author Reiner Jung
* @since 1.3.0
*
*/
public class ChartAssemblerStage extends AbstractTransformation<ExperimentLog, Chart> {
@Override
protected void execute(ExperimentLog element) throws Exception {
Chart chart = new Chart(element.getKind());
for (Experiment experiment : element.getExperiments()) {
long timestamp = Double.valueOf(experiment.getTimestamp()).longValue();
ValueTuple tuple = new ValueTuple(timestamp);
addHeaderIfMissing(chart.getHeaders(), experiment.getMeasurements());
fillInData(chart.getHeaders(), tuple.getValues(), experiment.getMeasurements());
chart.getValues().add(tuple);
}
this.outputPort.send(chart);
}
private void fillInData(List<String> headers, List<Double> values, Map<String, Measurements> measurements) {
for (String key : headers) {
Measurements value = measurements.get(key);
if (value != null) {
values.add(value.getMean());
} else
values.add(Double.NaN);
}
}
private void addHeaderIfMissing(List<String> headers, Map<String, Measurements> measurements) {
for (String key : measurements.keySet()) {
if (!headers.stream().anyMatch(header -> header.equals(key))) {
headers.add(key);
}
}
}
}
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
package moobench.tools.results; package moobench.tools.results;
import java.io.File; import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import com.beust.jcommander.JCommander; import com.beust.jcommander.JCommander;
......
/**
*
*/
package moobench.tools.results;
import java.util.List;
import java.util.Map.Entry;
import moobench.tools.results.data.Experiment;
import moobench.tools.results.data.ExperimentLog;
import moobench.tools.results.data.Measurements;
import moobench.tools.results.data.TableInformation;
import teetime.stage.basic.AbstractTransformation;
/**
* @author reiner
*
*/
public class ComputeTableStage extends AbstractTransformation<ExperimentLog, TableInformation> {
@Override
protected void execute(final ExperimentLog log) throws Exception {
final List<Experiment> experiments = log.getExperiments();
if (experiments.size() > 0) {
final Experiment current = experiments.get(experiments.size()-1);
int first = experiments.size() - 10;
int last = experiments.size() - 2;
if (first < 0) {
first = 0;
}
if (last < 0) {
last = 0;
}
final Experiment previous = new Experiment();
for (int i = first; i < last; i++) {
final Experiment experiment = experiments.get(i);
for (final Entry<String, Measurements> entry : experiment.getMeasurements().entrySet()) {
final Measurements measurements = entry.getValue();
if (!previous.getMeasurements().containsKey(entry.getKey())) {
previous.getMeasurements().put(entry.getKey(), measurements);
} else {
final Measurements previousMeasurements = previous.getMeasurements().get(entry.getKey());
previous.getMeasurements().put(entry.getKey(), this.computePrevious(previousMeasurements, measurements));
}
}
}
this.outputPort.send(new TableInformation(log.getKind(), current, previous));
}
}
private Measurements computePrevious(final Measurements previousMeasurements, final Measurements measurements) {
return new Measurements((measurements.getMean() + previousMeasurements.getMean())/2,
(measurements.getStandardDeviation() + previousMeasurements.getStandardDeviation())/2,
(measurements.getConvidence() + previousMeasurements.getConvidence())/2,
(measurements.getLowerQuartile() + previousMeasurements.getLowerQuartile())/2,
(measurements.getMedian() + previousMeasurements.getMedian())/2,
(measurements.getUpperQuartile() + previousMeasurements.getUpperQuartile())/2,
(measurements.getMin() + previousMeasurements.getMin())/2,
(measurements.getMax() + previousMeasurements.getMax())/2);
}
}
...@@ -25,8 +25,10 @@ public class ElementProducer<O> extends AbstractProducerStage<O> { ...@@ -25,8 +25,10 @@ public class ElementProducer<O> extends AbstractProducerStage<O> {
@Override @Override
protected void execute() throws Exception { protected void execute() throws Exception {
for (O element : elements) { for (O element : elements) {
this.logger.debug(String.format("Reading log %s", element));
this.outputPort.send(element); this.outputPort.send(element);
} }
this.workCompleted();
} }
} }
package moobench.tools.results;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import moobench.tools.results.data.OutputFile;
import teetime.framework.AbstractConsumerStage;
public class FileSink extends AbstractConsumerStage<OutputFile> {
@Override
protected void execute(final OutputFile outputFile) throws Exception {
try (final BufferedWriter writer = Files.newBufferedWriter(outputFile.getFilePath())) {
writer.write(outputFile.getContent());
writer.close();
} catch(final IOException e) {
this.logger.error("Cannot write file {}", outputFile.getFilePath().toString());
}
}
}
package moobench.tools.results;
import java.nio.file.Path;
import java.util.Set;
import moobench.tools.results.data.Measurements;
import moobench.tools.results.data.OutputFile;
import moobench.tools.results.data.TableInformation;
import teetime.stage.basic.AbstractTransformation;
public class GenerateHtmlTableStage extends AbstractTransformation<TableInformation, OutputFile> {
private final Path tablePath;
public GenerateHtmlTableStage(final Path tablePath) {
this.tablePath = tablePath;
}
@Override
protected void execute(final TableInformation element) throws Exception {
String content = "<table>\n" + " <tr>\n" + " <th>setup</th>\n" + " <th>run</th>\n"
+ " <th>mean</th>\n" + " <th>ci</th>\n" + " <th>sd</th>\n" + " <th>1.quartile</th>\n"
+ " <th>median</th>\n" + " <th>3.quartile</th>\n" + " <th>min</th>\n" + " <th>max</th>\n"
+ " </tr>\n";
final Set<String> currentKeySet = element.getCurrent().getMeasurements().keySet();
final Set<String> previousKeySet = element.getPrevious().getMeasurements().keySet();
final Set<String> completeKeySet = new OrderedSet<>();
if (currentKeySet != null) {
completeKeySet.addAll(currentKeySet);
}
if (previousKeySet != null) {
completeKeySet.addAll(previousKeySet);
}
for (final String key : completeKeySet) {
content += this.addMode(key, element.getCurrent().getMeasurements().get(key),
element.getPrevious().getMeasurements().get(key));
}
content += "</table>\n";
this.outputPort.send(new OutputFile(this.tablePath.resolve(element.getName() + ".html"), content));
}
private String addMode(final String key, final Measurements current, final Measurements previous) {
String result = "";
if (current != null) {
result = this.createRow(key, "current", current);
}
if (previous != null) {
result += this.createRow(key, "past", previous);
}
return result;
}
private String createRow(final String key, final String run, final Measurements measurements) {
final StringBuilder cells = new StringBuilder();
cells.append(String.format(" <td style=\"text-align: left;\">%s</td>\n", key));
cells.append(String.format(" <td style=\"text-align: left;\">%s</td>\n", run));
this.addDouble(cells, measurements.getMean());
this.addDouble(cells, measurements.getConvidence());
this.addDouble(cells, measurements.getStandardDeviation());
this.addDouble(cells, measurements.getLowerQuartile());
this.addDouble(cells, measurements.getMedian());
this.addDouble(cells, measurements.getUpperQuartile());
this.addDouble(cells, measurements.getMin());
this.addDouble(cells, measurements.getMax());
return String.format(" <tr>\n%s </tr>\n", cells.toString());
}
private StringBuilder addDouble(final StringBuilder cells, final Double value) {
return cells.append(String.format(" <td style=\"text-align: right;\">%1.2f</td>\n", value));
}
}
...@@ -2,46 +2,43 @@ package moobench.tools.results; ...@@ -2,46 +2,43 @@ package moobench.tools.results;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import moobench.tools.results.data.Chart;
import moobench.tools.results.data.ValueTuple;
import teetime.framework.AbstractConsumerStage; import teetime.framework.AbstractConsumerStage;
public class LogWriter extends AbstractConsumerStage<List<Map<String,JsonNode>>> { public class JsonLogSink extends AbstractConsumerStage<Chart> {
private Path logJson; private Path path;
public LogWriter(Path logJson) { public JsonLogSink(Path path) {
this.logJson = logJson; this.path = path;
} }
@Override @Override
protected void execute(List<Map<String,JsonNode>> list) throws Exception { protected void execute(Chart chart) throws Exception {
Path jsonLog = this.path.resolve(chart.getName() + ".json");
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
ObjectNode node = mapper.createObjectNode(); ObjectNode node = mapper.createObjectNode();
ArrayNode arrayNode = node.putArray("results"); ArrayNode arrayNode = node.putArray("results");
for(Map<String, JsonNode> map : list) { for(ValueTuple value : chart.getValues()) {
ObjectNode objectNode = mapper.createObjectNode(); ObjectNode objectNode = mapper.createObjectNode();
for (Entry<String, JsonNode> entry : map.entrySet()) { for (int i = 0;i < chart.getHeaders().size();i++) {
JsonNode value = entry.getValue(); String name = chart.getHeaders().get(i);
if (value.isDouble()) Double number = value.getValues().get(i);
objectNode.put(entry.getKey(), value.asDouble()); objectNode.put(name, number);
else if (value.isInt())
objectNode.put(entry.getKey(), value.asInt());
else
this.logger.warn("property {} is of type {}", entry.getKey(), value.getNodeType().toString());
} }
objectNode.put("time", value.getTimestamp());
arrayNode.add(objectNode); arrayNode.add(objectNode);
} }
mapper.writeValue(Files.newBufferedWriter(logJson), node); mapper.writeValue(Files.newBufferedWriter(jsonLog), node);
} }
} }
...@@ -3,56 +3,37 @@ ...@@ -3,56 +3,37 @@
*/ */
package moobench.tools.results; package moobench.tools.results;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import moobench.tools.results.data.Experiment; import moobench.tools.results.data.Experiment;
import moobench.tools.results.data.ExperimentLog; import moobench.tools.results.data.ExperimentLog;
import teetime.framework.AbstractStage; import teetime.framework.AbstractConsumerStage;
import teetime.framework.InputPort;
import teetime.framework.OutputPort; import teetime.framework.OutputPort;
/** /**
* @author Reiner Jung * @author Reiner Jung
* @since 1.3.0 * @since 1.3.0
*/ */
public class LogAppenderStage extends AbstractStage { public class LogAppenderStage extends AbstractConsumerStage<ExperimentLog> {
private final InputPort<ExperimentLog> newDataInputPort = this.createInputPort(ExperimentLog.class);
private final InputPort<ExperimentLog> logInputPort = this.createInputPort(ExperimentLog.class);
private final OutputPort<ExperimentLog> outputPort = this.createOutputPort(ExperimentLog.class); private final OutputPort<ExperimentLog> outputPort = this.createOutputPort(ExperimentLog.class);
private Map<String,ExperimentLog> logs; private Map<String,ExperimentLog> logs = new HashMap<>();
public InputPort<ExperimentLog> getNewDataInputPort() {
return newDataInputPort;
}
public InputPort<ExperimentLog> getLogInputPort() {
return logInputPort;
}
public OutputPort<ExperimentLog> getOutputPort() { public OutputPort<ExperimentLog> getOutputPort() {
return outputPort; return outputPort;
} }
@Override @Override
protected void execute() throws Exception { protected void execute(ExperimentLog log) throws Exception {
ExperimentLog newData = this.newDataInputPort.receive(); ExperimentLog presentLog = logs.get(log.getKind());
if (newData != null) {
appendData(newData);
}
ExperimentLog logData = this.logInputPort.receive();
if (logData != null) {
appendData(logData);
}
}
private void appendData(ExperimentLog newData) {
ExperimentLog presentLog = logs.get(newData.getKind());
if (presentLog != null) { if (presentLog != null) {
for (Experiment experiment : newData.getExperiments()) { for (Experiment experiment : log.getExperiments()) {
presentLog.getExperiments().add(experiment); presentLog.getExperiments().add(experiment);
} }
} else {
logs.put(log.getKind(), log);
} }
} }
......
/**
*
*/
package moobench.tools.results;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import teetime.framework.AbstractProducerStage;
/**
* @author reiner
*
*/
public class MainLogReader extends AbstractProducerStage<List<Map<String,JsonNode>>> {
private static final String RESULTS_LABEL = "results";
private final Path mainLogJson;
public MainLogReader(Path mainLogJson) {
this.mainLogJson = mainLogJson;
}
@Override
protected void execute() throws JsonProcessingException, IOException {
List<Map<String,JsonNode>> result = new ArrayList<Map<String,JsonNode>>();
JsonNode node;
if (Files.exists(mainLogJson)) {
node = readJsonFile();
} else {
node = readJsonString();
}
JsonNode resultsNode = node.get(RESULTS_LABEL);
if ((resultsNode instanceof ArrayNode)) {
ArrayNode arrayNode = (ArrayNode)resultsNode;
Iterator<JsonNode> iterator = arrayNode.elements();
while (iterator.hasNext()) {
JsonNode element = iterator.next();
if (element instanceof ObjectNode) {
ObjectNode objectNode = (ObjectNode)element;
Iterator<Entry<String, JsonNode>> elementIterator = objectNode.fields();
Map<String,JsonNode> row = new HashMap<>();
while (elementIterator.hasNext()) {
Entry<String, JsonNode> parameter = elementIterator.next();
row.put(parameter.getKey(), parameter.getValue());
}
result.add(row);
}
}
}
this.outputPort.send(result);
this.workCompleted();
}
private JsonNode readJsonString() throws JsonMappingException, JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String value = "{ \"results\" : [] }";
return mapper.readTree(value);
}
private JsonNode readJsonFile() throws JsonProcessingException, IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readTree(Files.newInputStream(mainLogJson));
}
}
package moobench.tools.results;
import java.nio.file.Path;
import java.util.Map;
import teetime.framework.AbstractProducerStage;
public class MappingFileReader extends AbstractProducerStage<Map<String,String>> {
public MappingFileReader(Path mappingFile) {
// TODO Auto-generated constructor stub
}
@Override
protected void execute() throws Exception {
// TODO Auto-generated method stub
this.workCompleted();
}
}
package moobench.tools.results;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import teetime.framework.AbstractStage;
import teetime.framework.InputPort;
import teetime.framework.OutputPort;
public class MergeDataStage extends AbstractStage {
private static final String BUILD_LABEL = "build";
private final InputPort<Map<String, String>> mappingInputPort = this.createInputPort();
private final InputPort<List<Map<String, JsonNode>>> mainLogInputPort = this.createInputPort();
private final InputPort<Map<String, JsonNode>> newDataInputPort = this.createInputPort();
private final OutputPort<List<Map<String, JsonNode>>> outputPort = this.createOutputPort();
private List<Map<String, JsonNode>> mainLog;
private List<Map<String, JsonNode>> bufferLog = new ArrayList<>();
private Map<String, String> mapping;
@Override
protected void execute() throws Exception {
List<Map<String, JsonNode>> log = this.mainLogInputPort.receive();
if (log != null) {
mainLog = log;
}
Map<String, String> newMapping = this.mappingInputPort.receive();
if (newMapping != null) {
mapping = newMapping;
}
Map<String, JsonNode> newData = this.newDataInputPort.receive();
if (newData != null) {
bufferLog.add(newData);
}
}
@Override
protected void onTerminating() {
moveNewData();
this.outputPort.send(mainLog);
super.onTerminating();
}
private void moveNewData() {
int last = mainLog.size()-1;
int build = mainLog.get(last).get(BUILD_LABEL).asInt() + 1;
Map<String,JsonNode> node = new HashMap<>();
node.put(BUILD_LABEL, new ObjectMapper().getNodeFactory().numberNode(build));
for (Map<String, JsonNode> data : bufferLog) {
for (Entry<String, JsonNode> entry : data.entrySet()) {
node.put(entry.getKey(), entry.getValue());
}
}
bufferLog.clear();
mainLog.add(node);
}
public InputPort<List<Map<String, JsonNode>>> getMainLogInputPort() {
return this.mainLogInputPort;
}
public InputPort<Map<String,String>> getMappingInputPort() {
return this.mappingInputPort;
}
public InputPort<Map<String,JsonNode>> getNewDataInputPort() {
return this.newDataInputPort ;
}
public OutputPort<List<Map<String, JsonNode>>> getOutputPort() {
return this.outputPort;
}
}
package moobench.tools.results;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
public class OrderedSet<T> extends ArrayList<T> implements Set<T> {
private static final long serialVersionUID = 719655465496957772L;
@Override
public boolean add(final T value) {
if (!super.contains(value)) {
return super.add(value);
} else {
return false;
}
}
@Override
public boolean addAll(final Collection<? extends T> values) {
boolean changed = false;
for(final T value : values) {
changed |= this.add(value);
}
return changed;
}
}
package moobench.tools.results;
import java.nio.file.Path;
import java.util.List;
import teetime.framework.AbstractProducerStage;
public class SpecialArrayElementStage extends AbstractProducerStage<Path> {
private List<Path> resultCsvPaths;
public SpecialArrayElementStage(List<Path> resultCsvPaths) {
this.resultCsvPaths = resultCsvPaths;
}
@Override
protected void execute() throws Exception {
for(Path path : resultCsvPaths) {
this.outputPort.send(path);
}
this.workCompleted();
}
}
/**
*
*/
package moobench.tools.results;
import moobench.tools.results.data.Chart;
import teetime.stage.basic.AbstractFilter;
/**
* @author reiner
*
*/
public class TailChartStage extends AbstractFilter<Chart> {
private Integer window;
public TailChartStage(Integer window) {
this.window = window;
}
@Override
protected void execute(Chart chart) throws Exception {
if (window != null) {
int size = chart.getValues().size();
if (size > window) {
Chart newChart = new Chart(chart.getName());
newChart.getHeaders().addAll(chart.getHeaders());
for (int i = size - window; i < size;i++) {
newChart.getValues().add(chart.getValues().get(i));
}
this.outputPort.send(newChart);
} else {
this.outputPort.send(chart);
}
} else {
this.outputPort.send(chart);
}
}
}
package moobench.tools.results; package moobench.tools.results;
import java.io.File;
import java.io.FilenameFilter;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.JsonNode;
import moobench.tools.results.data.ExperimentLog; import moobench.tools.results.data.ExperimentLog;
import teetime.framework.Configuration; import teetime.framework.Configuration;
...@@ -14,36 +13,62 @@ import teetime.stage.basic.distributor.strategy.CopyByReferenceStrategy; ...@@ -14,36 +13,62 @@ import teetime.stage.basic.distributor.strategy.CopyByReferenceStrategy;
public class TeetimeConfiguration extends Configuration { public class TeetimeConfiguration extends Configuration {
public TeetimeConfiguration(Settings settings) { public TeetimeConfiguration(final Settings settings) {
List<Path> logFilePaths = new ArrayList<Path>(); final List<Path> logFilePaths = this.createInputPaths(settings);
for (Path path : settings.getInputPaths()) {
logFilePaths.add(settings.getLogPath().resolve(path.getFileName()));
}
ElementProducer<Path> yamlInputPathsProducer = new ElementProducer<>(settings.getInputPaths()); final ElementProducer<Path> yamlInputPathsProducer = new ElementProducer<>(logFilePaths);
ElementProducer<Path> yamlLogPathsProducer = new ElementProducer<>(logFilePaths);
YamlReaderStage yamlInputReader = new YamlReaderStage(); final YamlReaderStage yamlInputReader = new YamlReaderStage();
YamlReaderStage yamlLogReader = new YamlReaderStage();
LogAppenderStage logAppenderStage = new LogAppenderStage(); final LogAppenderStage logAppenderStage = new LogAppenderStage();
Distributor<ExperimentLog> distributor = new Distributor<>(new CopyByReferenceStrategy()); final Distributor<ExperimentLog> distributor = new Distributor<>(new CopyByReferenceStrategy());
YamlLogSink yamlLogSink = new YamlLogSink(); final YamlLogSink yamlLogSink = new YamlLogSink(settings.getLogPath());
//ChartAssemblerStage :: chartAssemblerStage final ChartAssemblerStage chartAssemblerStage = new ChartAssemblerStage();
//JsonLogSink :: jsonLogSink final TailChartStage tailChartStage = new TailChartStage(settings.getWindow());
//GenerateHtmlTable :: generateHtmlTable final JsonLogSink jsonLogSink = new JsonLogSink(settings.getJsonLogPath());
//FileSink :: fileSink final ComputeTableStage computeTableStage = new ComputeTableStage();
final GenerateHtmlTableStage generateHtmlTableStage = new GenerateHtmlTableStage(settings.getTablePath());
final FileSink fileSink = new FileSink();
this.connectPorts(yamlInputPathsProducer.getOutputPort(), yamlInputReader.getInputPort()); this.connectPorts(yamlInputPathsProducer.getOutputPort(), yamlInputReader.getInputPort());
this.connectPorts(yamlLogPathsProducer.getOutputPort(), yamlLogReader.getInputPort()); this.connectPorts(yamlInputReader.getOutputPort(), logAppenderStage.getInputPort());
this.connectPorts(yamlInputReader.getOutputPort(), logAppenderStage.getNewDataInputPort());
this.connectPorts(yamlLogReader.getOutputPort(), logAppenderStage.getLogInputPort());
this.connectPorts(logAppenderStage.getOutputPort(), distributor.getInputPort()); this.connectPorts(logAppenderStage.getOutputPort(), distributor.getInputPort());
this.connectPorts(distributor.getNewOutputPort(), yamlLogSink.getInputPort()); this.connectPorts(distributor.getNewOutputPort(), yamlLogSink.getInputPort());
this.connectPorts(distributor.getNewOutputPort(), chartAssemblerStage.getInputPort());
this.connectPorts(distributor.getNewOutputPort(), computeTableStage.getInputPort());
this.connectPorts(computeTableStage.getOutputPort(), generateHtmlTableStage.getInputPort());
this.connectPorts(generateHtmlTableStage.getOutputPort(), fileSink.getInputPort());
this.connectPorts(chartAssemblerStage.getOutputPort(), tailChartStage.getInputPort());
this.connectPorts(tailChartStage.getOutputPort(), jsonLogSink.getInputPort());
}
private List<Path> createInputPaths(final Settings settings) {
final ArrayList<Path> logFilePaths = new ArrayList<Path>();
for (final Path path : settings.getInputPaths()) {
logFilePaths.add(path);
}
final FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(final File file, final String name) {
final int last = name.lastIndexOf(".");
if (last < 0) {
return false;
}
final String extension = name.substring(last+1);
return "yaml".equals(extension);
}
};
for (final File file : settings.getLogPath().toFile().listFiles(filter)) {
logFilePaths.add(file.toPath());
}
return logFilePaths;
} }
} }
package moobench.tools.results; package moobench.tools.results;
import java.io.FileWriter;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;
import moobench.tools.results.data.ExperimentLog; import moobench.tools.results.data.ExperimentLog;
import moobench.tools.results.data.Measurements;
import teetime.framework.AbstractConsumerStage; import teetime.framework.AbstractConsumerStage;
public class YamlLogSink extends AbstractConsumerStage<ExperimentLog> { public class YamlLogSink extends AbstractConsumerStage<ExperimentLog> {
Path logPath;
public YamlLogSink(Path logPath) {
this.logPath = logPath;
}
@Override @Override
protected void execute(ExperimentLog element) throws Exception { protected void execute(ExperimentLog log) throws Exception {
// TODO Auto-generated method stub Path logPath = this.logPath.resolve(String.format("%s.yaml", log.getKind()));
Representer representer = new LogRepresenter();
DumperOptions options = new DumperOptions();
Yaml yaml = new Yaml(representer, options);
FileWriter writer = new FileWriter(logPath.toFile());
yaml.dump(log, writer);
}
private class LogRepresenter extends Representer {
public LogRepresenter() {
this.representers.put(Measurements.class, new RepresentMeasurements());
}
private class RepresentMeasurements implements Represent {
@Override
public Node representData(Object data) {
Measurements measurements = (Measurements)data;
List<Double> values = new ArrayList<>();
values.add(measurements.getMean());
values.add(measurements.getStandardDeviation());
values.add(measurements.getConvidence());
values.add(measurements.getLowerQuartile());
values.add(measurements.getMedian());
values.add(measurements.getUpperQuartile());
values.add(measurements.getMin());
values.add(measurements.getMax());
return representSequence(new Tag("!!" + Measurements.class.getCanonicalName()), values, defaultFlowStyle);
}
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment