package org.spotter.ext.detection.olb.strategies;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
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.records.CPUUtilizationRecord;
import org.aim.artifacts.records.NetworkInterfaceInfoRecord;
import org.aim.artifacts.records.NetworkRecord;
import org.aim.artifacts.records.ResponseTimeRecord;
import org.aim.artifacts.records.SQLQueryRecord;
import org.lpe.common.util.LpeNumericUtils;
import org.lpe.common.util.LpeStringUtils;
import org.lpe.common.util.NumericPair;
import org.lpe.common.util.NumericPairList;
import org.lpe.common.util.system.LpeSystemUtils;
import org.spotter.core.chartbuilder.AnalysisChartBuilder;
import org.spotter.core.detection.AbstractDetectionController;
import org.spotter.ext.detection.olb.IOLBAnalysisStrategy;
import org.spotter.ext.detection.olb.OLBDetectionController;
import org.spotter.ext.detection.olb.OLBExtension;
import org.spotter.shared.result.model.SpotterResult;
/**
* Utilizes queueing theory to detect a One Lane Bridge.
*
* @author Alexander Wert
*
*/
public class QTStrategy implements IOLBAnalysisStrategy {
private static final double ONE_PLUS_EPSILON = 1.1;
private static final long MS_IN_SECOND = 1000L;
private OLBDetectionController mainDetectionController;
private static final long SPEED_100MBIT = 100000000;
private static final double SIG_LEVEL = 0.05;
private static final int NUM_REQ_SIG_STEPS = 2;
private String scope;
@Override
public SpotterResult analyze(DatasetCollection data) {
SpotterResult result = new SpotterResult();
Dataset rtDataset = data.getDataSet(ResponseTimeRecord.class);
if (rtDataset == null || rtDataset.size() == 0) {
result.setDetected(false);
result.addMessage("Instrumentation achieved no response time results for the given scope!");
return result;
}
Dataset cpuUtilDataset = data.getDataSet(CPUUtilizationRecord.class);
if (cpuUtilDataset == null || cpuUtilDataset.size() == 0) {
result.setDetected(false);
result.addMessage("Instrumentation achieved no CPU utilization results for the given scope!");
return result;
}
Dataset networkInfoDataset = data.getDataSet(NetworkInterfaceInfoRecord.class);
if (networkInfoDataset == null || networkInfoDataset.size() == 0) {
result.setDetected(false);
result.addMessage("Instrumentation achieved no networkInfoDataset results for the given scope!");
return result;
}
Dataset networkIODataset = data.getDataSet(NetworkRecord.class);
if (networkIODataset == null || networkIODataset.size() == 0) {
result.setDetected(false);
result.addMessage("Instrumentation achieved no netowrk IO results for the given scope!");
return result;
}
List<Integer> numUsersList = getNumUsersList(rtDataset);
Map<String, NumericPairList<Integer, Double>> responseTimesMap = null;
if (scope.equals(OLBExtension.DB_SCOPE)) {
Dataset sqlDataset = data.getDataSet(SQLQueryRecord.class);
if (sqlDataset == null || sqlDataset.size() == 0) {
result.setDetected(false);
result.addMessage("Instrumentation achieved no SQL results for the given scope!");
return result;
}
responseTimesMap = getOperationResponseTimesWithSQL(rtDataset, sqlDataset, result, numUsersList);
} else {
responseTimesMap = getOperationResponseTimes(rtDataset, result, numUsersList);
}
Map<String, NumericPairList<Integer, Double>> utilsMap = getCPUUtilizations(cpuUtilDataset, result,
numUsersList);
utilsMap.putAll(getNetworkUtilizations(networkIODataset, networkInfoDataset, result, numUsersList));
Map<String, Integer> numServersMap = getNumberOfCPUCores(cpuUtilDataset);
numServersMap.putAll(getNumberServers(networkInfoDataset));
// List<String> candidateOperations =
// analyseResponseTimesIncrease(result, numUsersList, responseTimesMap);
// Set<String> operations = new HashSet<>();
// operations.addAll(responseTimesMap.keySet());
// for (String operation : operations) {
// if (!candidateOperations.contains(operation)) {
// responseTimesMap.remove(operation);
// }
// }
analyzeOLB(result, numUsersList, responseTimesMap, utilsMap, numServersMap);
return result;
}
private List<String> analyseResponseTimesIncrease(SpotterResult result, List<Integer> numUsersList,
Map<String, NumericPairList<Integer, Double>> responseTimesMap) {
List<String> guiltyOperations = new ArrayList<>();
for (String operation : responseTimesMap.keySet()) {
try {
int prevNumUsers = -1;
int firstSignificantNumUsers = -1;
int significantSteps = 0;
List<Double> prevValues = null;
for (Integer numUsers : numUsersList) {
if (prevNumUsers > 0) {
List<Double> currentValues = LpeNumericUtils.filterOutliersUsingIQR(getValuesForNumUsers(
responseTimesMap.get(operation), numUsers));
prevValues = LpeNumericUtils.filterOutliersUsingIQR(getValuesForNumUsers(
responseTimesMap.get(operation), prevNumUsers));
List<Double> sums1 = new ArrayList<>();
List<Double> sums2 = new ArrayList<>();
LpeNumericUtils
.createNormalDistributionByBootstrapping(prevValues, currentValues, sums1, sums2);
if (sums2.size() < 2 || sums1.size() < 2) {
throw new IllegalArgumentException("OLB detection failed for the operation '" + operation
+ "', because there are not enough measurement points for a t-test.");
}
double prevMean = LpeNumericUtils.average(sums1);
double currentMean = LpeNumericUtils.average(sums2);
double pValue = LpeNumericUtils.tTest(sums2, sums1);
if (pValue >= 0 && pValue <= SIG_LEVEL && prevMean < currentMean) {
if (firstSignificantNumUsers < 0) {
firstSignificantNumUsers = prevNumUsers;
}
significantSteps++;
} else {
firstSignificantNumUsers = -1;
significantSteps = 0;
}
}
prevNumUsers = numUsers;
}
if (firstSignificantNumUsers > 0 && significantSteps >= NUM_REQ_SIG_STEPS) {
guiltyOperations.add(operation);
}
} catch (Exception e) {
}
}
return guiltyOperations;
}
private void analyzeOLB(SpotterResult result, List<Integer> numUsersList,
Map<String, NumericPairList<Integer, Double>> responseTimesMap,
Map<String, NumericPairList<Integer, Double>> utilsMap, Map<String, Integer> numServersMap) {
Set<String> utilsChartsCreatedFor = new HashSet<>();
Map<String, Double> operationScales = new HashMap<>();
Map<String, NumericPairList<Integer, Double>> rtThresholdsForChart = new HashMap<String, NumericPairList<Integer, Double>>();
Map<String, NumericPairList<Integer, Double>> chartResponseTimes = new HashMap<String, NumericPairList<Integer, Double>>();
operationLoop: for (String operation : responseTimesMap.keySet()) {
NumericPairList<Integer, Double> responseTimes = responseTimesMap.get(operation);
double singleUserResponseTime = 0;
try {
singleUserResponseTime = getValueForNumUsers(responseTimes, responseTimes.getKeyMin());
} catch (Exception e) {
continue operationLoop;
}
singleUserResponseTime = Math.max(singleUserResponseTime, 15.0);
boolean qtDetected = true;
int i = 0;
Map<Integer, Double> thresholds = new HashMap<>();
boolean fixThresholdExceeded = false;
for (String rersourceID : utilsMap.keySet()) {
NumericPairList<Integer, Double> utils = utilsMap.get(rersourceID);
int numServers = numServersMap.get(rersourceID);
createUtilChart(result, utilsChartsCreatedFor, rersourceID, utils);
for (int numUsers : numUsersList) {
double utilization = getValueForNumUsers(utils, numUsers);
if(utilization>0.9){
fixThresholdExceeded=true;
}
double saveUtil = Math.min(0.999, utilization + 0.1);
if (!thresholds.containsKey(numUsers)) {
thresholds.put(numUsers, 0.0);
}
// response time threshold derived from queueing theory for
// multi-server queues
double t = singleUserResponseTime / (numServers * (1 - saveUtil))
* LpeNumericUtils.calculateErlangsCFormula(numServers, saveUtil) + singleUserResponseTime;
thresholds.put(numUsers, Math.max(t, thresholds.get(numUsers)));
}
}
if(fixThresholdExceeded){
continue operationLoop;
}
rtThresholdsForChart.put(operation, new NumericPairList<Integer, Double>());
chartResponseTimes.put(operation, new NumericPairList<Integer, Double>());
boolean responseTimesUnderThresholdCurve = true;
double maxResponseTime = Double.MIN_VALUE;
for (int numUsers : numUsersList) {
double responseTime = 0.0;
try {
responseTime = getValueForNumUsers(responseTimes, numUsers);
maxResponseTime = Math.max(maxResponseTime, responseTime);
} catch (Exception e) {
continue operationLoop;
}
if (i < numUsersList.size()) {
chartResponseTimes.get(operation).add(numUsers, responseTime);
}
if (responseTime > thresholds.get(numUsers)) {
responseTimesUnderThresholdCurve = false;
}
rtThresholdsForChart.get(operation).add(numUsers, thresholds.get(numUsers));
i++;
}
if (!responseTimesUnderThresholdCurve) {
operationScales.put(operation, maxResponseTime);
}
}
double sum = 0.0;
for (Double d : operationScales.values()) {
sum += d;
}
for (String op : operationScales.keySet()) {
double scale = operationScales.get(op);
operationScales.put(op, scale / sum);
}
List<Entry<String, Double>> sortedEntryList = new ArrayList<>();
sortedEntryList.addAll(operationScales.entrySet());
Collections.sort(sortedEntryList, new Comparator<Entry<String, Double>>() {
@Override
public int compare(Entry<String, Double> o1, Entry<String, Double> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
double sumPercent = 0.0;
for (Entry<String, Double> entry : sortedEntryList) {
result.setDetected(true);
result.addMessage("OLB detected in service: " + entry.getKey());
createDetectedChart(result, entry.getKey(), chartResponseTimes.get(entry.getKey()),
rtThresholdsForChart.get(entry.getKey()));
sumPercent += entry.getValue();
if (sumPercent >= 0.8) {
break;
}
}
}
private void createRTChart(SpotterResult result, String operation, NumericPairList<Integer, Double> responseTimes) {
AnalysisChartBuilder chartBuilder = AnalysisChartBuilder.getChartBuilder();
String operationName = operation.contains("(") ? operation.substring(0, operation.indexOf("(")) : operation;
chartBuilder
.startChart(operationName, "number of users", "response time [ms]");
chartBuilder.addScatterSeries(responseTimes, "avg. response times");
mainDetectionController.getResultManager().storeImageChartResource(chartBuilder, "Response Times", result);
}
private void createDetectedChart(SpotterResult result, String operation,
NumericPairList<Integer, Double> responseTimes, NumericPairList<Integer, Double> rtThresholdsForChart) {
AnalysisChartBuilder chartBuilder = AnalysisChartBuilder.getChartBuilder();
String operationName = operation.contains("(") ? operation.substring(0, operation.indexOf("(")) : operation;
chartBuilder.startChart(operationName, "number of users", "response time [ms]");
chartBuilder.addScatterSeriesWithLine(responseTimes, "avg. response times");
chartBuilder.addLineSeries(rtThresholdsForChart, "response times threshold");
mainDetectionController.getResultManager().storeImageChartResource(chartBuilder, "Detected", result);
}
private void createUtilChart(SpotterResult result, Set<String> utilsChartsCreatedFor, String resourceId,
NumericPairList<Integer, Double> cpuUtils) {
AnalysisChartBuilder chartBuilder = null;
if (!utilsChartsCreatedFor.contains(resourceId)) {
chartBuilder = AnalysisChartBuilder.getChartBuilder();
chartBuilder.startChart("CPU on " + resourceId, "number of users", "utilization [%]");
chartBuilder.addUtilizationLineSeries(cpuUtils, "utilization", true);
mainDetectionController.getResultManager().storeImageChartResource(chartBuilder,
"Utilization-" + resourceId, result);
utilsChartsCreatedFor.add(resourceId);
}
}
private double getValueForNumUsers(NumericPairList<Integer, Double> pairList, int numUsers) {
List<Double> values = getValuesForNumUsers(pairList, numUsers);
if (!values.isEmpty()) {
return LpeNumericUtils.average(values);
}
throw new IllegalArgumentException("Data not found!");
}
private List<Double> getValuesForNumUsers(NumericPairList<Integer, Double> pairList, int numUsers) {
List<Double> values = new ArrayList<>();
for (NumericPair<Integer, Double> pair : pairList) {
if (pair.getKey().equals(numUsers)) {
values.add(pair.getValue());
}
}
return values;
}
private List<Integer> getNumUsersList(Dataset rtDataset) {
List<Integer> numUsersList = new ArrayList<>(rtDataset.getValueSet(
AbstractDetectionController.NUMBER_OF_USERS_KEY, Integer.class));
Collections.sort(numUsersList);
return numUsersList;
}
private Map<String, NumericPairList<Integer, Double>> getOperationResponseTimes(Dataset rtDataset,
SpotterResult result, final List<Integer> numUsersList) {
Map<String, NumericPairList<Integer, Double>> resultMap = new HashMap<>();
operationLoop: for (String operation : rtDataset.getValueSet(ResponseTimeRecord.PAR_OPERATION, String.class)) {
NumericPairList<Integer, Double> responseTimePairList = new NumericPairList<>();
for (Integer numUsers : numUsersList) {
ParameterSelection selection = new ParameterSelection().select(
AbstractDetectionController.NUMBER_OF_USERS_KEY, numUsers).select(
ResponseTimeRecord.PAR_OPERATION, operation);
Dataset tmpRTDataset = selection.applyTo(rtDataset);
if (tmpRTDataset == null || tmpRTDataset.size() == 0) {
result.addMessage("One Lane Bridge detection failed for the operation '" + operation
+ "', because the operation was not executed in each analysis cycle. "
+ "Hence, the operation cannot be analyzed for an OLB.");
continue operationLoop;
}
List<Long> responseTimes = tmpRTDataset.getValues(ResponseTimeRecord.PAR_RESPONSE_TIME, Long.class);
for (Long rt : responseTimes) {
responseTimePairList.add(numUsers, rt.doubleValue());
}
}
resultMap.put(operation, responseTimePairList);
createRTChart(result, operation, responseTimePairList);
}
return resultMap;
}
private Map<String, NumericPairList<Integer, Double>> getOperationResponseTimesWithSQL(Dataset rtDataset,
Dataset sqlDataset, SpotterResult result, final List<Integer> numUsersList) {
Map<String, NumericPairList<Integer, Double>> resultMap = new HashMap<>();
List<SQLQueryRecord> sqlRecords = sqlDataset.getRecords(SQLQueryRecord.class);
operationLoop: for (String operation : rtDataset.getValueSet(ResponseTimeRecord.PAR_OPERATION, String.class)) {
if (operation.contains("execute")) {
Map<String, String> queryMap = new HashMap<>();
Map<String, NumericPairList<Integer, Double>> rtMap = new HashMap<>();
for (Integer numUsers : numUsersList) {
ParameterSelection selection = new ParameterSelection().select(
AbstractDetectionController.NUMBER_OF_USERS_KEY, numUsers).select(
ResponseTimeRecord.PAR_OPERATION, operation);
Dataset tmpRTDataset = selection.applyTo(rtDataset);
if (tmpRTDataset == null || tmpRTDataset.size() == 0) {
result.addMessage("One Lane Bridge detection failed for the operation '" + operation
+ "', because the operation was not executed in each analysis cycle. "
+ "Hence, the operation cannot be analyzed for an OLB.");
continue operationLoop;
}
Map<String, List<Long>> responsetimesMap = new HashMap<>();
for (ResponseTimeRecord rtRecord : tmpRTDataset.getRecords(ResponseTimeRecord.class)) {
SQLQueryRecord sqlRecord = findRecordForCallID(sqlRecords, rtRecord.getCallId());
if (sqlRecord == null) {
continue;
}
String sql = null;
try {
sql = LpeStringUtils.getGeneralizedQuery(sqlRecord.getQueryString());
if (sql == null) {
sql = sqlRecord.getQueryString();
if (sql.contains("$")) {
int idx_1 = sql.indexOf(",", sql.indexOf("$"));
int idx_2 = sql.indexOf(" ", sql.indexOf("$"));
idx_1 = idx_1 < 0 ? Integer.MAX_VALUE : idx_1;
idx_2 = idx_2 < 0 ? Integer.MAX_VALUE : idx_2;
int endIndex = Math.min(idx_1, idx_2);
String name = sql.substring(sql.indexOf("$"), endIndex);
sql = sql.replace(name, "tmp");
}
}
} catch (Exception e) {
continue;
}
int hash = sql.hashCode();
String opName = hash + " - " + operation;
if (!responsetimesMap.containsKey(opName)) {
responsetimesMap.put(opName, new ArrayList<Long>());
}
if (!queryMap.containsKey(opName)) {
queryMap.put(opName, sql);
}
if (!rtMap.containsKey(opName)) {
rtMap.put(opName, new NumericPairList<Integer, Double>());
}
List<Long> rtList = responsetimesMap.get(opName);
rtList.add(rtRecord.getResponseTime());
}
for (String opName : responsetimesMap.keySet()) {
List<Long> responseTimes = responsetimesMap.get(opName);
NumericPairList<Integer, Double> responseTimePairList = rtMap.get(opName);
for (Long rt : responseTimes) {
responseTimePairList.add(numUsers, rt.doubleValue());
}
}
}
storeQueryMap(queryMap, result);
for (String opName : rtMap.keySet()) {
resultMap.put(opName, rtMap.get(opName));
createRTChart(result, opName, resultMap.get(opName));
}
} else {
NumericPairList<Integer, Double> responseTimePairList = new NumericPairList<>();
for (Integer numUsers : numUsersList) {
ParameterSelection selection = new ParameterSelection().select(
AbstractDetectionController.NUMBER_OF_USERS_KEY, numUsers).select(
ResponseTimeRecord.PAR_OPERATION, operation);
Dataset tmpRTDataset = selection.applyTo(rtDataset);
if (tmpRTDataset == null || tmpRTDataset.size() == 0) {
result.addMessage("One Lane Bridge detection failed for the operation '" + operation
+ "', because the operation was not executed in each analysis cycle. "
+ "Hence, the operation cannot be analyzed for an OLB.");
continue operationLoop;
}
List<Long> responseTimes = tmpRTDataset.getValues(ResponseTimeRecord.PAR_RESPONSE_TIME, Long.class);
double meanResponseTime = LpeNumericUtils.average(responseTimes);
responseTimePairList.add(numUsers, meanResponseTime);
}
resultMap.put(operation, responseTimePairList);
}
}
return resultMap;
}
private void storeQueryMap(final Map<String, String> queryMap, SpotterResult result) {
try {
final PipedOutputStream outStream = new PipedOutputStream();
PipedInputStream inStream = new PipedInputStream(outStream);
LpeSystemUtils.submitTask(new Runnable() {
@Override
public void run() {
BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(outStream));
try {
for (Entry<String, String> entry : queryMap.entrySet()) {
bWriter.write(entry.getKey() + " : " + entry.getValue());
bWriter.newLine();
}
} catch (IOException e) {
} finally {
if (bWriter != null) {
try {
bWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
});
mainDetectionController.getResultManager().storeTextResource("QueryMap", result, inStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private SQLQueryRecord findRecordForCallID(List<SQLQueryRecord> sqlRecords, long callID) {
for (SQLQueryRecord rec : sqlRecords) {
if (rec.getCallId() == callID) {
return rec;
}
}
return null;
}
private Map<String, NumericPairList<Integer, Double>> getCPUUtilizations(Dataset cpuUtilDataset,
SpotterResult result, final List<Integer> numUsersList) {
Map<String, NumericPairList<Integer, Double>> resultMap = new HashMap<>();
for (String processID : cpuUtilDataset.getValueSet(CPUUtilizationRecord.PAR_PROCESS_ID, String.class)) {
NumericPairList<Integer, Double> cpuUtilPairList = new NumericPairList<>();
for (Integer numUsers : numUsersList) {
ParameterSelection selection = new ParameterSelection()
.select(AbstractDetectionController.NUMBER_OF_USERS_KEY, numUsers)
.select(CPUUtilizationRecord.PAR_PROCESS_ID, processID)
.select(CPUUtilizationRecord.PAR_CPU_ID, CPUUtilizationRecord.RES_CPU_AGGREGATED);
Dataset tmpCPUUtilDataset = selection.applyTo(cpuUtilDataset);
List<Double> cpuUtils = tmpCPUUtilDataset.getValues(CPUUtilizationRecord.PAR_UTILIZATION, Double.class);
double meanCPUUtil = LpeNumericUtils.average(cpuUtils);
cpuUtilPairList.add(numUsers, meanCPUUtil);
}
resultMap.put(processID + " - " + CPUUtilizationRecord.RES_CPU_AGGREGATED, cpuUtilPairList);
}
return resultMap;
}
private Map<String, NumericPairList<Integer, Double>> getNetworkUtilizations(Dataset networkIODataset,
Dataset networkInfoDataset, SpotterResult result, final List<Integer> numUsersList) {
Map<String, NumericPairList<Integer, Double>> resultMap = new HashMap<>();
for (String processID : networkInfoDataset.getValueSet(NetworkInterfaceInfoRecord.PAR_PROCESS_ID, String.class)) {
ParameterSelection processSelection = ParameterSelection.newSelection().select(
NetworkInterfaceInfoRecord.PAR_PROCESS_ID, processID);
Dataset processSpecificDataset = processSelection.applyTo(networkInfoDataset);
for (String nwInterfaceName : processSpecificDataset.getValueSet(
NetworkInterfaceInfoRecord.PAR_NETWORK_INTERFACE, String.class)) {
ParameterSelection nwInterfaceSelection = ParameterSelection.newSelection().select(
NetworkInterfaceInfoRecord.PAR_NETWORK_INTERFACE, nwInterfaceName);
Dataset nwInterfaceSpecificDataset = nwInterfaceSelection.applyTo(processSpecificDataset);
long tmpSpeed = nwInterfaceSpecificDataset.getValues(NetworkInterfaceInfoRecord.PAR_INTERFACE_SPEED,
Long.class).get(0);
if (tmpSpeed < 0L) {
tmpSpeed = SPEED_100MBIT;
}
double speed = ((double) tmpSpeed) / 8.0;
NumericPairList<Integer, Double> networkUtilPairList = new NumericPairList<>();
for (Integer numUsers : numUsersList) {
if (tmpSpeed == 0L) {
networkUtilPairList.add(numUsers, 0.0);
continue;
}
Dataset tmpNetowrkIODataset = ParameterSelection.newSelection()
.select(AbstractDetectionController.NUMBER_OF_USERS_KEY, numUsers)
.select(NetworkRecord.PAR_PROCESS_ID, processID)
.select(NetworkRecord.PAR_NETWORK_INTERFACE, nwInterfaceName).applyTo(networkIODataset);
List<Long> timestamps = tmpNetowrkIODataset.getValues(NetworkRecord.PAR_TIMESTAMP, Long.class);
long minTimestamp = LpeNumericUtils.min(timestamps);
long maxTimestamp = LpeNumericUtils.max(timestamps);
List<Long> receivedBytes = tmpNetowrkIODataset.getValues(NetworkRecord.PAR_RECEIVED_BYTES,
Long.class);
long minReceivedBytes = LpeNumericUtils.min(receivedBytes);
long maxReceivedBytes = LpeNumericUtils.max(receivedBytes);
List<Long> transferredBytes = tmpNetowrkIODataset.getValues(NetworkRecord.PAR_TRANSFERRED_BYTES,
Long.class);
long minTransferredBytes = LpeNumericUtils.min(transferredBytes);
long maxTransferredBytes = LpeNumericUtils.max(transferredBytes);
double utilReceived = (((double) (MS_IN_SECOND * (maxReceivedBytes - minReceivedBytes))) / ((double) (maxTimestamp - minTimestamp)))
/ speed;
double utilTransferred = (((double) (MS_IN_SECOND * (maxTransferredBytes - minTransferredBytes))) / ((double) (maxTimestamp - minTimestamp)))
/ speed;
networkUtilPairList.add(numUsers, Math.max(utilReceived, utilTransferred));
}
resultMap.put(processID + " - " + nwInterfaceName, networkUtilPairList);
}
}
return resultMap;
}
private Map<String, Integer> getNumberServers(Dataset networkInfoDataset) {
Map<String, Integer> numServers = new HashMap<>();
for (String processID : networkInfoDataset.getValueSet(NetworkInterfaceInfoRecord.PAR_PROCESS_ID, String.class)) {
ParameterSelection processSelection = ParameterSelection.newSelection().select(
NetworkInterfaceInfoRecord.PAR_PROCESS_ID, processID);
Dataset processSpecificDataset = processSelection.applyTo(networkInfoDataset);
for (String nwInterfaceName : processSpecificDataset.getValueSet(
NetworkInterfaceInfoRecord.PAR_NETWORK_INTERFACE, String.class)) {
numServers.put(processID + " - " + nwInterfaceName, 1);
}
}
return numServers;
}
private Map<String, Integer> getNumberOfCPUCores(Dataset cpuUtilDataset) {
Map<String, Integer> cpuNumCores = new HashMap<>();
for (String processID : cpuUtilDataset.getValueSet(CPUUtilizationRecord.PAR_PROCESS_ID, String.class)) {
ParameterSelection selection = new ParameterSelection().select(CPUUtilizationRecord.PAR_PROCESS_ID,
processID);
int numCores = selection.applyTo(cpuUtilDataset).getValueSet(CPUUtilizationRecord.PAR_CPU_ID).size() - 1;
cpuNumCores.put(processID + " - " + CPUUtilizationRecord.RES_CPU_AGGREGATED, numCores);
}
return cpuNumCores;
}
@Override
public void setProblemDetectionConfiguration(Properties problemDetectionConfiguration) {
scope = problemDetectionConfiguration.getProperty(OLBExtension.SCOPE_KEY, OLBExtension.ENTRY_SCOPE);
}
@Override
public void setMainDetectionController(OLBDetectionController mainDetectionController) {
this.mainDetectionController = mainDetectionController;
}
}