blob: 77892530c4a9ca0d3dd3ab617110660ba465fe04 [file] [log] [blame]
package org.eclipse.emf.henshin.monitoring.kieker.analysis;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.eclipse.emf.henshin.monitoring.kieker.records.UnitExecutionStartRecord;
import org.eclipse.emf.henshin.monitoring.kieker.records.UnitExecutionStopRecord;
import org.eclipse.emf.henshin.monitoring.kieker.util.RuleExecutionData;
import org.eclipse.emf.henshin.monitoring.ui.HenshinPerformanceView;
import org.eclipse.emf.henshin.monitoring.ui.util.RuleVisualizationData;
import org.eclipse.emf.henshin.monitoring.ui.util.UnitVisualizationData;
import kieker.analysis.AnalysisController;
import kieker.analysis.IAnalysisController;
import kieker.analysis.exception.AnalysisConfigurationException;
import kieker.analysis.plugin.reader.filesystem.FSReader;
import kieker.common.configuration.Configuration;
import kieker.common.record.AbstractMonitoringRecord;
public class PerformanceAnalysis {
private static FSReader reader;
private static final Configuration filterConfig = new Configuration();
private static final IAnalysisController analysisController = new AnalysisController();
private static LinkedList<RuleExecutionData> ruleCalls;
private static LinkedList<UnitVisualizationData> unitCallData;
private static LinkedList<AbstractMonitoringRecord> startStopRecords;
private static HashMap<UnitExecutionStartRecord,Integer> startRecordToRuleCallsIdx;
/**
* Starts analysis and calls view.
*/
public static void runPerformanceAnalysis(){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ruleCalls=new LinkedList<RuleExecutionData>();
unitCallData=new LinkedList<UnitVisualizationData>();
startStopRecords=new LinkedList<AbstractMonitoringRecord>();
startRecordToRuleCallsIdx=new HashMap<UnitExecutionStartRecord,Integer>();
String kiekerDir=getLogFilePath();
collectRecords(kiekerDir);
updateUnitCalls(0,unitCallData);
LinkedList<RuleVisualizationData> ruleVisualizationData=new LinkedList<RuleVisualizationData>();
for(RuleExecutionData rule:ruleCalls){
rule.setVisualizationData();
ruleVisualizationData.add(rule.getRuleVisualizations());
}
//Open GUI
HenshinPerformanceView.showHenshinPerformanceView(ruleVisualizationData,unitCallData);
}
/**
* Extracts the call hierarchy from a list of UnitExecutionStartRecord and UnitExecutionStopRecord records.
*
* @param listIdx Index of the current record to be processed
* @param callTree Data structure presenting the call hierarchy
*
* @return Index of the current record to be processed after the call of updateUnitCalls
*/
private static int updateUnitCalls(int listIdx,LinkedList<UnitVisualizationData> callTree){
final String ruleType="Rule";
for(;listIdx<startStopRecords.size()-1;listIdx++){
if((startStopRecords.get(listIdx) instanceof UnitExecutionStartRecord)&&(startStopRecords.get(listIdx+1) instanceof UnitExecutionStopRecord)){
//Start-Stop: Simple transformation rule execution or Empty Unit
UnitExecutionStartRecord startRec=(UnitExecutionStartRecord) startStopRecords.get(listIdx);
UnitExecutionStopRecord stopRec=(UnitExecutionStopRecord) startStopRecords.get(listIdx+1);
UnitVisualizationData data=new UnitVisualizationData(startRec.getUnitName(),startRec.getStartTimeStamp(),stopRec.getStopTimeStamp(),startRec.getType());
if(startRec.getType().equals(ruleType)){
data.setTabIdx(startRecordToRuleCallsIdx.get(startRec)+1);
}
callTree.add(data);
listIdx++; //Start and Stop record are processed
}else if((startStopRecords.get(listIdx) instanceof UnitExecutionStartRecord)&&(startStopRecords.get(listIdx+1) instanceof UnitExecutionStartRecord)){
//Start-Start: One step deeper into the call hierarchy
UnitExecutionStartRecord startRec=(UnitExecutionStartRecord) startStopRecords.get(listIdx); //Recorde der andere Aufruft
LinkedList<UnitVisualizationData> deeperCall=new LinkedList<UnitVisualizationData>();
int idxAfter=updateUnitCalls((listIdx+1),deeperCall);
//It is expected that idxAfter after the recursion points to the stop record which belongs to the start record at the beginning of the recursion.
if(!(startStopRecords.get(idxAfter) instanceof UnitExecutionStopRecord)){
System.err.println("There is an error in the log files please rerun the transformation.");
return startStopRecords.size();
}
UnitExecutionStopRecord stopRec=(UnitExecutionStopRecord) startStopRecords.get(idxAfter);
UnitVisualizationData data=new UnitVisualizationData(startRec.getUnitName(),startRec.getStartTimeStamp(),stopRec.getStopTimeStamp(),startRec.getType());
data.setCalls(deeperCall);
callTree.add(data);
listIdx=idxAfter; //Start and Stop record are processed
}else if((startStopRecords.get(listIdx) instanceof UnitExecutionStopRecord)&& (listIdx>0)){
if((startStopRecords.get(listIdx-1) instanceof UnitExecutionStopRecord)){
//Start-Start: One step back in the call hierarchy
return listIdx;
}
}else{
System.err.println("There is an error in the log files please rerun the transformation.");
return startStopRecords.size();
}
}
return listIdx;
}
/**
* Looks for the path in the temp directory which contains the latest monitoring data
*
*
* @return Path to the directory containing the latest monitoring data
*/
private static String getLogFilePath(){
String kiekerPath="";
File fileTemp = new File(System.getProperty("java.io.tmpdir"));
long modified=-1;
if(fileTemp.isDirectory()){
for(String tmpFiles:fileTemp.list()){
if(tmpFiles.startsWith("kieker-")){
File kiekerDir = new File((System.getProperty("java.io.tmpdir")+tmpFiles));
if(modified<kiekerDir.lastModified()){
kiekerPath=System.getProperty("java.io.tmpdir")+tmpFiles;
modified=kiekerDir.lastModified();
}
}
}
}
return kiekerPath;
}
/**
* Collects the data records from given directory
* @param kiekerDir Path to directory containing the monitoring records
*/
private static void collectRecords(String kiekerDir){
if((new File(kiekerDir)).exists()){
final Configuration fsReaderConfig = new Configuration();
fsReaderConfig.setProperty(FSReader.CONFIG_PROPERTY_NAME_INPUTDIRS,kiekerDir);
reader = new FSReader(fsReaderConfig,analysisController);
final PerformanceFilter performanceFilter = new PerformanceFilter(filterConfig,analysisController,ruleCalls,startStopRecords,startRecordToRuleCallsIdx);
try{
analysisController.connect(reader, FSReader.OUTPUT_PORT_NAME_RECORDS,performanceFilter,PerformanceFilter.INPUT_PORT_NAME_PERFORMANCE_VISUALIZATION);
analysisController.run();
}catch(IllegalStateException | AnalysisConfigurationException e) {
e.printStackTrace();
}
}
}
}