preparation to add plots for percentiles
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
package org.lucares.pdb.plot.api;
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
public enum AggreateInternal {
|
public enum AggreateInternal {
|
||||||
NONE, MEAN
|
NONE, MEAN, PERCENTILE95, PERCENTILE99, PERCENTILE999
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.lucares.recommind.logs.DataSeries;
|
||||||
|
|
||||||
|
public interface AggregateHandler {
|
||||||
|
|
||||||
|
void addStats(StringBuilder result, Collection<DataSeries> dataSeries);
|
||||||
|
|
||||||
|
default void appendfln(final StringBuilder builder, final String format, final Object... args) {
|
||||||
|
builder.append(String.format(format + "\n", args));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPlots(StringBuilder result, Collection<DataSeries> dataSeries);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.lucares.recommind.logs.DataSeries;
|
||||||
|
|
||||||
|
public class MeanAggregate implements AggregateHandler{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addStats(StringBuilder result, Collection<DataSeries> dataSeries) {
|
||||||
|
int count = 1;
|
||||||
|
for (final DataSeries dataSerie : dataSeries) {
|
||||||
|
|
||||||
|
appendfln(result, "stats '%s' using 2 prefix \"A%d\"", dataSerie.getDataFile(),count);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPlots(StringBuilder result, Collection<DataSeries> dataSeries) {
|
||||||
|
int count = 1;
|
||||||
|
for (final DataSeries dataSerie : dataSeries) {
|
||||||
|
appendfln(result, "A%d_mean title '%s Mean', \\", count,
|
||||||
|
dataSerie.getTitle(), dataSerie.getTitle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.lucares.recommind.logs.DataSeries;
|
||||||
|
|
||||||
|
public class NullAggregate implements AggregateHandler {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addStats(StringBuilder result, Collection<DataSeries> dataSeries) {
|
||||||
|
// nothing to do; this is a Null-Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPlots(StringBuilder result, Collection<DataSeries> dataSeries) {
|
||||||
|
// nothing to do; this is a Null-Object
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ public class PlotSettings {
|
|||||||
|
|
||||||
private AxisScale yAxisScale;
|
private AxisScale yAxisScale;
|
||||||
|
|
||||||
private AggreateInternal aggregate;
|
private AggregateHandler aggregate;
|
||||||
|
|
||||||
private boolean keyOutside;
|
private boolean keyOutside;
|
||||||
|
|
||||||
@@ -163,11 +163,11 @@ public class PlotSettings {
|
|||||||
+ ", axisScale=" + yAxisScale + ", aggregate="+aggregate+", keyOutside="+keyOutside+"]";
|
+ ", axisScale=" + yAxisScale + ", aggregate="+aggregate+", keyOutside="+keyOutside+"]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAggregate(AggreateInternal aggregate) {
|
public void setAggregate(AggregateHandler aggregate) {
|
||||||
this.aggregate = aggregate;
|
this.aggregate = aggregate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AggreateInternal getAggregate() {
|
public AggregateHandler getAggregate() {
|
||||||
return aggregate;
|
return aggregate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,24 @@
|
|||||||
package org.lucares.recommind.logs;
|
package org.lucares.recommind.logs;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
|
||||||
class CsvSummary {
|
class CsvSummary {
|
||||||
private final int values;
|
private final int values;
|
||||||
private long maxValue;
|
private long maxValue;
|
||||||
|
private File dataFile;
|
||||||
|
|
||||||
public CsvSummary(final int values, long maxValue) {
|
public CsvSummary(File dataFile, final int values, long maxValue) {
|
||||||
super();
|
super();
|
||||||
|
this.dataFile = dataFile;
|
||||||
this.values = values;
|
this.values = values;
|
||||||
this.maxValue = maxValue;
|
this.maxValue = maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getDataFile() {
|
||||||
|
return dataFile;
|
||||||
|
}
|
||||||
|
|
||||||
public int getValues() {
|
public int getValues() {
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,7 @@ public class GnuplotFileGenerator {
|
|||||||
|
|
||||||
appendfln(result, "set datafile separator \"%s\"", settings.getDatafileSeparator());
|
appendfln(result, "set datafile separator \"%s\"", settings.getDatafileSeparator());
|
||||||
|
|
||||||
int count = 1;
|
settings.getAggregate().addStats(result, dataSeries);
|
||||||
if (settings.getAggregate() != AggreateInternal.NONE)
|
|
||||||
{
|
|
||||||
for (final DataSeries dataSerie : dataSeries) {
|
|
||||||
|
|
||||||
appendfln(result, "stats '%s' using 2 prefix \"A%d\"", dataSerie.getDataFile(),count);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
appendfln(result, "set timefmt '%s'", settings.getTimefmt());
|
appendfln(result, "set timefmt '%s'", settings.getTimefmt());
|
||||||
|
|
||||||
@@ -67,16 +59,11 @@ public class GnuplotFileGenerator {
|
|||||||
|
|
||||||
appendf(result, "plot ");
|
appendf(result, "plot ");
|
||||||
|
|
||||||
count = 1;
|
|
||||||
for (final DataSeries dataSerie : dataSeries) {
|
for (final DataSeries dataSerie : dataSeries) {
|
||||||
appendfln(result, "'%s' using 1:2 title '%s' with points, \\", dataSerie.getDataFile(),
|
appendfln(result, "'%s' using 1:2 title '%s' with points, \\", dataSerie.getDataFile(),
|
||||||
dataSerie.getTitle());
|
dataSerie.getTitle());
|
||||||
if (settings.getAggregate() == AggreateInternal.MEAN) {
|
|
||||||
appendfln(result, "A%d_mean title '%s Mean', \\", count, dataSerie.getTitle(),
|
|
||||||
dataSerie.getTitle());
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
|
settings.getAggregate().addPlots(result, dataSeries);
|
||||||
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.lucares.recommind.logs;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import org.lucares.pdb.plot.api.AggreateInternal;
|
import org.lucares.pdb.plot.api.AggreateInternal;
|
||||||
|
import org.lucares.pdb.plot.api.AggregateHandler;
|
||||||
import org.lucares.pdb.plot.api.AxisScale;
|
import org.lucares.pdb.plot.api.AxisScale;
|
||||||
|
|
||||||
public class GnuplotSettings {
|
public class GnuplotSettings {
|
||||||
@@ -31,7 +32,7 @@ public class GnuplotSettings {
|
|||||||
private AxisScale yAxisScale;
|
private AxisScale yAxisScale;
|
||||||
private String dateFrom;
|
private String dateFrom;
|
||||||
private String dateTo;
|
private String dateTo;
|
||||||
private AggreateInternal aggregate;
|
private AggregateHandler aggregate;
|
||||||
private boolean keyOutside = false;
|
private boolean keyOutside = false;
|
||||||
|
|
||||||
public GnuplotSettings(final Path output) {
|
public GnuplotSettings(final Path output) {
|
||||||
@@ -138,11 +139,11 @@ public class GnuplotSettings {
|
|||||||
return dateTo;
|
return dateTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAggregate(AggreateInternal aggregate) {
|
public void setAggregate(AggregateHandler aggregate) {
|
||||||
this.aggregate = aggregate;
|
this.aggregate = aggregate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AggreateInternal getAggregate() {
|
public AggregateHandler getAggregate() {
|
||||||
return aggregate;
|
return aggregate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import org.lucares.pdb.api.Entry;
|
|||||||
import org.lucares.pdb.api.GroupResult;
|
import org.lucares.pdb.api.GroupResult;
|
||||||
import org.lucares.pdb.api.Result;
|
import org.lucares.pdb.api.Result;
|
||||||
import org.lucares.pdb.api.Tags;
|
import org.lucares.pdb.api.Tags;
|
||||||
|
import org.lucares.pdb.plot.api.AggreateInternal;
|
||||||
|
import org.lucares.pdb.plot.api.AggregateHandler;
|
||||||
import org.lucares.pdb.plot.api.Limit;
|
import org.lucares.pdb.plot.api.Limit;
|
||||||
import org.lucares.pdb.plot.api.PlotSettings;
|
import org.lucares.pdb.plot.api.PlotSettings;
|
||||||
import org.lucares.performance.db.PerformanceDb;
|
import org.lucares.performance.db.PerformanceDb;
|
||||||
@@ -94,11 +96,10 @@ public class Plotter {
|
|||||||
|
|
||||||
final Stream<Entry> entries = groupResult.asStream();
|
final Stream<Entry> entries = groupResult.asStream();
|
||||||
|
|
||||||
final File dataFile = File.createTempFile("data", ".dat", tmpDir.toFile());
|
final CsvSummary csvSummary = toCsv(entries, tmpDir, dateFrom, dateTo, plotSettings);
|
||||||
final CsvSummary csvSummary = toCsv(entries, dataFile, dateFrom, dateTo);
|
|
||||||
|
|
||||||
final String title = title(groupResult.getGroupedBy(), csvSummary.getValues());
|
final String title = title(groupResult.getGroupedBy(), csvSummary.getValues());
|
||||||
final DataSeries dataSerie = new DataSeries(dataFile, title, csvSummary.getValues(), csvSummary.getMaxValue());
|
final DataSeries dataSerie = new DataSeries(csvSummary.getDataFile(), title, csvSummary.getValues(), csvSummary.getMaxValue());
|
||||||
if (dataSerie.getValues() > 0) {
|
if (dataSerie.getValues() > 0) {
|
||||||
dataSeries.add(dataSerie);
|
dataSeries.add(dataSerie);
|
||||||
}
|
}
|
||||||
@@ -223,14 +224,17 @@ public class Plotter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CsvSummary toCsv(final Stream<Entry> entries, final File dataFile, final OffsetDateTime dateFrom,
|
private static CsvSummary toCsv(final Stream<Entry> entries, final Path tmpDir, final OffsetDateTime dateFrom,
|
||||||
final OffsetDateTime dateTo) throws IOException {
|
final OffsetDateTime dateTo, PlotSettings plotSettings) throws IOException {
|
||||||
|
|
||||||
|
final File dataFile = File.createTempFile("data", ".dat", tmpDir.toFile());
|
||||||
final long start = System.nanoTime();
|
final long start = System.nanoTime();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
final long fromEpochMilli = dateFrom.toInstant().toEpochMilli();
|
final long fromEpochMilli = dateFrom.toInstant().toEpochMilli();
|
||||||
final long toEpochMilli = dateTo.toInstant().toEpochMilli();
|
final long toEpochMilli = dateTo.toInstant().toEpochMilli();
|
||||||
final boolean useMillis = (toEpochMilli - fromEpochMilli) < TimeUnit.MINUTES.toMillis(5);
|
final boolean useMillis = (toEpochMilli - fromEpochMilli) < TimeUnit.MINUTES.toMillis(5);
|
||||||
|
final AggregateHandler aggregate = plotSettings.getAggregate();
|
||||||
|
|
||||||
|
|
||||||
long maxValue = 0;
|
long maxValue = 0;
|
||||||
long ignoredValues = 0;
|
long ignoredValues = 0;
|
||||||
@@ -271,7 +275,7 @@ public class Plotter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
METRICS_LOGGER.debug("wrote {} values to csv in: {}ms (ignored {} values) use millis: {}", count, (System.nanoTime() - start) / 1_000_000.0, ignoredValues, Boolean.toString(useMillis));
|
METRICS_LOGGER.debug("wrote {} values to csv in: {}ms (ignored {} values) use millis: {}", count, (System.nanoTime() - start) / 1_000_000.0, ignoredValues, Boolean.toString(useMillis));
|
||||||
return new CsvSummary(count, maxValue);
|
return new CsvSummary(dataFile, count, maxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String longToString(final long value){
|
private static String longToString(final long value){
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package org.lucares.pdbui;
|
package org.lucares.pdbui;
|
||||||
|
|
||||||
import org.lucares.pdb.plot.api.AggreateInternal;
|
import org.lucares.pdb.plot.api.AggreateInternal;
|
||||||
|
import org.lucares.pdb.plot.api.AggregateHandler;
|
||||||
import org.lucares.pdb.plot.api.AxisScale;
|
import org.lucares.pdb.plot.api.AxisScale;
|
||||||
import org.lucares.pdb.plot.api.Limit;
|
import org.lucares.pdb.plot.api.Limit;
|
||||||
|
import org.lucares.pdb.plot.api.MeanAggregate;
|
||||||
|
import org.lucares.pdb.plot.api.NullAggregate;
|
||||||
import org.lucares.pdb.plot.api.PlotSettings;
|
import org.lucares.pdb.plot.api.PlotSettings;
|
||||||
import org.lucares.pdbui.domain.Aggregate;
|
import org.lucares.pdbui.domain.Aggregate;
|
||||||
import org.lucares.pdbui.domain.LimitBy;
|
import org.lucares.pdbui.domain.LimitBy;
|
||||||
@@ -29,10 +32,13 @@ class PlotSettingsTransformer {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AggreateInternal toAggregateInternal(Aggregate aggregate) {
|
private static AggregateHandler toAggregateInternal(Aggregate aggregate) {
|
||||||
switch (aggregate) {
|
switch (aggregate) {
|
||||||
case NONE:return AggreateInternal.NONE;
|
case NONE:return new NullAggregate();
|
||||||
case MEAN:return AggreateInternal.MEAN;
|
case MEAN:return new MeanAggregate();
|
||||||
|
case PERCENTILE95:return new NullAggregate();
|
||||||
|
case PERCENTILE99:return new NullAggregate();
|
||||||
|
case PERCENTILE999:return new NullAggregate();
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("unhandled enum: " + aggregate);
|
throw new IllegalStateException("unhandled enum: " + aggregate);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package org.lucares.pdbui.domain;
|
package org.lucares.pdbui.domain;
|
||||||
|
|
||||||
public enum Aggregate {
|
public enum Aggregate {
|
||||||
NONE, MEAN
|
NONE, MEAN, PERCENTILE95, PERCENTILE99, PERCENTILE999
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,9 @@
|
|||||||
<select id="show-aggregate">
|
<select id="show-aggregate">
|
||||||
<option value="NONE" selected="selected">-</option>
|
<option value="NONE" selected="selected">-</option>
|
||||||
<option value="MEAN">Mean</option>
|
<option value="MEAN">Mean</option>
|
||||||
|
<option value="PERCENTILE95">95% percentile</option>
|
||||||
|
<option value="PERCENTILE99">99% percentile</option>
|
||||||
|
<option value="PERCENTILE999">99.9% percentile</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="group">
|
<div class="group">
|
||||||
|
|||||||
Reference in New Issue
Block a user