package org.spotter.ext.detection.ramp.strategies; import java.util.Properties; import org.aim.api.exceptions.InstrumentationException; import org.aim.api.exceptions.MeasurementException; import org.aim.api.measurement.dataset.Dataset; import org.aim.api.measurement.dataset.DatasetCollection; import org.aim.api.measurement.dataset.ParameterSelection; import org.aim.artifacts.probes.ResponsetimeProbe; import org.aim.artifacts.records.ResponseTimeRecord; import org.aim.artifacts.scopes.EntryPointScope; import org.aim.description.InstrumentationDescription; import org.aim.description.builder.InstrumentationDescriptionBuilder; import org.apache.commons.math3.stat.regression.SimpleRegression; import org.lpe.common.util.LpeNumericUtils; import org.lpe.common.util.NumericPairList; import org.spotter.core.ProgressManager; import org.spotter.core.chartbuilder.AnalysisChartBuilder; import org.spotter.ext.detection.ramp.IRampDetectionStrategy; import org.spotter.ext.detection.ramp.RampDetectionController; import org.spotter.ext.detection.ramp.RampExtension; import org.spotter.ext.detection.utils.Utils; import org.spotter.shared.result.model.SpotterResult; public class LinearRegressionStrategy implements IRampDetectionStrategy { private RampDetectionController mainDetectionController; private double slopeThreshold = RampExtension.LIN_SLOPE_DEFAULT; @Override public void setProblemDetectionConfiguration(Properties problemDetectionConfiguration) { String slopeThresholdStr = problemDetectionConfiguration.getProperty(RampExtension.KEY_LIN_SLOPE); slopeThreshold = slopeThresholdStr != null ? Double.parseDouble(slopeThresholdStr) : RampExtension.LIN_SLOPE_DEFAULT; } @Override public void setMainDetectionController(RampDetectionController mainDetectionController) { this.mainDetectionController = mainDetectionController; } @Override public void executeExperiments() throws InstrumentationException, MeasurementException { mainDetectionController.executeHighLoadExperiment(getInstrumentationDescription()); } @Override public SpotterResult analyze(DatasetCollection data) { SpotterResult result = new SpotterResult(); result.setDetected(false); Dataset rtDataset = data.getDataSet(ResponseTimeRecord.class); if (rtDataset == null || rtDataset.size() == 0) { result.setDetected(false); result.addMessage("Instrumentation achieved no results for the given scope!"); return result; } for (String operation : rtDataset.getValueSet(ResponseTimeRecord.PAR_OPERATION, String.class)) { ParameterSelection selectOperation = new ParameterSelection().select(ResponseTimeRecord.PAR_OPERATION, operation); Dataset operationSpecificDataset = selectOperation.applyTo(rtDataset); NumericPairList<Long, Double> responseTimeSeries = Utils.toTimestampRTPairs(operationSpecificDataset); // sort chronologically responseTimeSeries.sort(); SimpleRegression regression = LpeNumericUtils.linearRegression(responseTimeSeries); double slope = regression.getSlope(); if (slope > slopeThreshold) { result.addMessage("Ramp detected in operation: " + operation); result.setDetected(true); } createChart(result, operation, responseTimeSeries, regression); } return result; } private void createChart(SpotterResult result, String operation, NumericPairList<Long, Double> responseTimeSeries, SimpleRegression regression) { NumericPairList<Long, Double> linRegressionPoints = new NumericPairList<>(); NumericPairList<Long, Double> thresholdPoints = new NumericPairList<>(); long minTimestamp = responseTimeSeries.getKeyMin(); long maxTimestamp = responseTimeSeries.getKeyMax(); double intercept = regression.predict(minTimestamp); linRegressionPoints.add(minTimestamp, intercept); linRegressionPoints.add(maxTimestamp, regression.predict(maxTimestamp)); thresholdPoints.add(minTimestamp, intercept); thresholdPoints.add(maxTimestamp, slopeThreshold * (double) (maxTimestamp - minTimestamp) + intercept); AnalysisChartBuilder chartBuilder = AnalysisChartBuilder.getChartBuilder(); chartBuilder.startChart(operation, "Experiment Time [ms]", "Response Time [ms]"); // chartBuilder.addTimeSeries(responseTimeSeries, "Response Times"); chartBuilder.addTimeSeriesWithLine(thresholdPoints, "Threshold Slope"); chartBuilder.addTimeSeriesWithLine(linRegressionPoints, "Regression Slope"); mainDetectionController.getResultManager().storeImageChartResource(chartBuilder, "Ramp Detection (Lin)", result); } @Override public long getExperimentSeriesDuration() { return ProgressManager.getInstance().calculateDefaultExperimentSeriesDuration(1); } public InstrumentationDescription getInstrumentationDescription() { InstrumentationDescriptionBuilder idBuilder = new InstrumentationDescriptionBuilder(); idBuilder.newAPIScopeEntity(EntryPointScope.class.getName()).addProbe(ResponsetimeProbe.MODEL_PROBE) .entityDone(); return idBuilder.build(); } }